我正在尝试创建一个考试应用程序,用户可以在其中添加多个问题,每个问题可能包含图像。这里我使用的是expressjs、reactjs、multer、mongodb。
问题是,当用户以 quertion1Data: "xxx", Question1Image: file, quertion2Data: "xxx", Question2Image: file 等表单数据发送多个问题数据时(我真的不知道如何发送多个问题) formdata 中的数据,比如我应该以什么方式发送,我提到的方式是否正确?而且我只在nodejs 中工作,我的其他团队成员在reactjs 中工作)。我如何首先使用 multer 将 Question1 的文件存储在我的服务器中的文件夹中,然后获取其路径,将其存储在 mongodb 中,获取其 _id,并将其与其他 Question1 字段链接,最后将 Question1 存储到 mongodb 并执行以下操作与其他问题相同。
路线如下:
router.post("/addQuestions", authTeacherAdminSuperAdmin('Questions.Create'), uploadFile({ multipleImages: 'image' }), QuestionController.addQuestions);
中间件看起来像这样:
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');
const { array } = require('joi');
function createDynamicFolders(folderPath) {
if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath, { recursive: true });
}
}
function uploadFile(options) {
const storage = multer.diskStorage({
destination: (req, file, cb) => {
console.log('Dynamic folder: ', req.dynamicFolder);
const folderPath = ./public/uploads/${req.user.orgId}/${req.user.id}/${req.dynamicFolder};
createDynamicFolders(folderPath);
cb(null, folderPath);
},
filename: (req, file, cb) => {
const ext = path.extname(file.originalname);
const uniqueFilename = ${Date.now()}${ext};
cb(null, uniqueFilename);
}
});
const upload = multer({ storage: storage });
return function (req, res, next) {
console.log(options, "options")
console.log(options, "options")
console.log('Uploading file for field:', options.fieldName);
if (Array.isArray(options)) {
upload.fields(options)(req, res, async function (err) {
if (err) {
console.error('Error during file upload:', err);
return res.status(500).json({ message: 'File Upload Error: ' + err.message });
}
next();
});
} else if (options.fieldName) {
upload.single(options.fieldName)(req, res, async function (err) {
if (err) {
console.error('Error during file upload:', err);
return res.status(500).json({ message: 'File Upload Error: ' + err.message });
}
// // Check if the uploaded file is an image (you might want to add more validation)
// if (req.file.mimetype.startsWith('image')) {
// // Resize the image using Sharp
// const resizedImagePath = ./public/uploads/${req.user.orgId}/${req.user.id}/${req.dynamicFolder}/resized_${req.file.filename};
// await sharp(req.file.path)
// .resize(300, 200, { fit: 'inside' })
// .toFile(resizedImagePath);
// // You can save the resized image path or perform further actions with it
// req.resizedImagePath = resizedImagePath;
// }
next();
});
} else {
upload.array(options.multipleImages)(req, res, async function (err) {
if (err) {
console.error('Error during file upload:', err);
return res.status(500).json({ message: 'File Upload Error: ' + err.message });
}
req.files = req.files.map((item, index) => ({ ...item, index }));
next();
});
}
};
}
module.exports = uploadFile;
创建函数如下所示:
static create = async (data) => {
try {
let questions = []
for (let index = 0; index < data.questions.length; index++) {
const question = data.questions[index];
if (question.image && Object.keys(question.image).length > 0) {
const addImage = await FileServices.addFile(question.image);
question.image = addImage._id
} else {
delete question.image
}
questions.push(question)
}
const result = {
...data,
questions: questions.map((question) => ({
...question,
organizationId: data.organizationId,
deleted: data.deleted ? data.deleted : false,
createdBy: data.createdBy
}))
};
if (result.questions.length > 0) {
const promises = result.questions.map(item => QuestionModel.create(item));
return await Promise.all(promises)
}
} catch (error) {
throw error;
}
}