gpt4 book ai didi

strapi - 如何在 Strapi 中复制/克隆记录?

转载 作者:行者123 更新时间:2023-12-03 23:27:40 40 4
gpt4 key购买 nike

我想从数据库中另一条记录的克隆开始,而不必再次填写所有这些字段。目前这是非常乏味的,必须打开两个选项卡(一个带有现有记录,另一个带有新记录)并复制粘贴数据。

如何在 Strapi 中克隆/复制记录?

最佳答案

您需要在 editing extensions guide 之后编辑此文件

├───admin
│ └───src
│ ├───containers
│ │ ├───EditView
│ │ │ Header.js
│ │ └───EditViewDataManagerProvider
│ │ │ index.js
│ │ └───utils
│ │ cleanData.js
│ │ index.js
│ └───translations
│ en.json
├───config
│ routes.json
├───controllers
│ ContentManager.js
└───services
ContentManager.js

Header.js



if (!isCreatingEntry) {
headerActions.unshift(
{
label: formatMessage({
id: `${pluginId}.containers.Edit.clone`,
}),
color: 'primary',
onClick: (e) => {
handleClone(e);
},
type: 'button',
style: {
paddingLeft: 15,
paddingRight: 15,
fontWeight: 600,
},
},
{
label: formatMessage({
id: 'app.utils.delete',
}),
color: 'delete',
onClick: () => {
toggleWarningDelete();
},
type: 'button',
style: {
paddingLeft: 15,
paddingRight: 15,
fontWeight: 600,
},
},
);
}

并通过 handleClone这里

const {
deleteSuccess,
initialData,
layout,
redirectToPreviousPage,
resetData,
handleClone,
setIsSubmitting,
slug,
clearData,
} = useDataManager();

EditViewDataManagerProvider/index.js



const handleClone = async (event) => {
event.preventDefault();

// Create yup schema
const schema = createYupSchema(
currentContentTypeLayout,
{
components: get(allLayoutData, 'components', {}),
},
true
);

try {
// Validate the form using yup
await schema.validate(modifiedData, { abortEarly: false });
// Set the loading state in the plugin header
const filesToUpload = getFilesToUpload(modifiedData);
// Remove keys that are not needed
// Clean relations
const cleanedData = cleanData(
cloneDeep(modifiedData),
currentContentTypeLayout,
allLayoutData.components,
true
);

const formData = new FormData();

formData.append('data', JSON.stringify(cleanedData));

Object.keys(filesToUpload).forEach((key) => {
const files = filesToUpload[key];

files.forEach((file) => {
formData.append(`files.${key}`, file);
});
});

// Change the request helper default headers so we can pass a FormData
const headers = {};
const method = 'POST';
const endPoint = `${slug}/clone/${modifiedData.id}`;

emitEvent(isCreatingEntry ? 'willCloneEntry' : 'willCloneEntry');

try {
// Time to actually send the data
await request(
getRequestUrl(endPoint),
{
method,
headers,
body: formData,
signal,
},
false,
false
);
emitEvent(isCreatingEntry ? 'didCloneEntry' : 'didCloneEntry');
dispatch({
type: 'CLONE_SUCCESS',
});
strapi.notification.success(`${pluginId}.success.record.clone`);
// strapi.notification.success('Entry cloned!');

redirectToPreviousPage();
} catch (err) {
console.error({ err });
const error = get(
err,
['response', 'payload', 'message', '0', 'messages', '0', 'id'],
'SERVER ERROR'
);

setIsSubmitting(false);
emitEvent(isCreatingEntry ? 'didNotCloneEntry' : 'didNotCloneEntry', {
error: err,
});
strapi.notification.error(error);
}
} catch (err) {
const errors = getYupInnerErrors(err);
console.error({ err, errors });

dispatch({
type: 'CLONE_ERRORS',
errors,
});
}
};

并提供 handleClone到 EditViewDataManagerContext.Provider.value

EditViewDataManagerProvider/utils/cleanData.js



const cleanData = (retrievedData, currentSchema, componentsSchema, clone = false) => {
const getType = (schema, attrName) =>
get(schema, ['attributes', attrName, 'type'], '');
const getSchema = (schema, attrName) =>
get(schema, ['attributes', attrName], '');
const getOtherInfos = (schema, arr) =>
get(schema, ['attributes', ...arr], '');

const recursiveCleanData = (data, schema) => Object.keys(data).reduce((acc, current) => {
const attrType = getType(schema.schema, current);
const valueSchema = getSchema(schema.schema, current);
const value = get(data, current);
const component = getOtherInfos(schema.schema, [current, 'component']);
const isRepeatable = getOtherInfos(schema.schema, [
current,
'repeatable',
]);
let cleanedData;


switch (attrType) {
case 'string': {
if (clone && valueSchema.unique) {
cleanedData = `${value}_clone`;
} else {
cleanedData = value;
}
break;
}
case 'json':
try {
cleanedData = JSON.parse(value);
} catch (err) {
cleanedData = value;
}

break;
case 'date':
case 'datetime':
cleanedData =
value && value._isAMomentObject === true
? value.toISOString()
: value;
break;
case 'media':
if (getOtherInfos(schema.schema, [current, 'multiple']) === true) {
cleanedData = value
? helperCleanData(
value.filter(file => !(file instanceof File)),
'id'
)
: null;
} else {
cleanedData =
get(value, 0) instanceof File ? null : get(value, 'id', null);
}
break;
case 'component':
if (isRepeatable) {
cleanedData = value
? value.map((data) => {
const subCleanedData = recursiveCleanData(
data,
componentsSchema[component]
);

return subCleanedData;
})
: value;
} else {
cleanedData = value
? recursiveCleanData(value, componentsSchema[component])
: value;
}
break;
case 'dynamiczone':
cleanedData = value.map((componentData) => {
const subCleanedData = recursiveCleanData(
componentData,
componentsSchema[componentData.__component]
);

return subCleanedData;
});
break;
default:
cleanedData = helperCleanData(value, 'id');
}


acc[current] = cleanedData;

if (clone && (current === '_id' || current === 'id')) {
acc[current] = undefined;
}

return acc;
}, {});

return recursiveCleanData(retrievedData, currentSchema);
};

just copy EditViewDataManagerProvider/utils/index.js

add in config/routes.json



{
"method": "POST",
"path": "/explorer/:model/clone/:id",
"handler": "ContentManager.clone",
"config": {
"policies": ["routing"]
}
}


add similar to create clone method in controllers/ContentManager.js



async clone(ctx) {
const contentManagerService = strapi.plugins['content-manager'].services.contentmanager;

const { model } = ctx.params;

try {
if (ctx.is('multipart')) {
const { data, files } = parseMultipartBody(ctx);
ctx.body = await contentManagerService.clone(data, { files, model });
} else {
// Create an entry using `queries` system
ctx.body = await contentManagerService.clone(ctx.request.body, { model });
}

// await strapi.telemetry.send('didCreateFirstContentTypeEntry', { model });
} catch (error) {
strapi.log.error(error);
ctx.badRequest(null, [
{
messages: [{ id: error.message, message: error.message, field: error.field }],
errors: _.get(error, 'data.errors'),
},
]);
}
},

and finally services/ContentManager.js



  clone(data, { files, model } = {}) {
return strapi.entityService.create({ data, files }, { model });
},

不要忘记更新 translations/:lang.json 中的翻译
"containers.Edit.clone": "clone button",
"success.record.clone": "notification"

不要忘记重建您的管理 UI
npm run build

关于strapi - 如何在 Strapi 中复制/克隆记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60522438/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com