feat: upload car image
Some checks failed
ms-devops/pipeline/head There was a failure building this commit
ms-devops/pipeline/pr-master There was a failure building this commit

This commit is contained in:
RustamRu
2025-02-22 16:58:58 +03:00
parent 30c9c86c93
commit df21879c0d
4 changed files with 228 additions and 1 deletions

View File

@@ -0,0 +1,27 @@
const { Schema, model } = require('mongoose')
const schema = new Schema({
file: String,
orderId: {
type: Schema.Types.ObjectId,
ref: 'dry-wash-order'
},
created: {
type: Date,
default: () => new Date().toISOString(),
},
})
schema.set('toJSON', {
virtuals: true,
versionKey: false,
transform(_doc, ret) {
delete ret._id
}
})
schema.virtual('id').get(function () {
return this._id.toHexString()
})
exports.OrderCarImgModel = model('dry-wash-order-car-image', schema)

View File

@@ -1,7 +1,9 @@
const mongoose = require("mongoose")
const router = require('express').Router()
const multer = require('multer')
const { MasterModel } = require('./model/master')
const { OrderModel } = require('./model/order')
const { OrderCarImgModel } = require('./model/order.car-img')
const { orderStatus } = require('./model/const')
const isValidPhoneNumber = (value) => /^(\+)?\d{9,15}/.test(value)
@@ -26,6 +28,9 @@ const isValidLocation = (value) => {
const isValidOrderStatus = (value) => Object.values(orderStatus).includes(value)
const isValidOrderNotes = (value) => value.length < 500
const allowedMimeTypes = ['image/jpeg', 'image/png']
const sizeLimitInMegaBytes = 5
const VALIDATION_MESSAGES = {
order: {
notFound: 'Order not found'
@@ -60,6 +65,13 @@ const VALIDATION_MESSAGES = {
carColor: {
invalid: 'Invalid car color'
},
carImg: {
required: 'Car image file is required',
invalid: {
type: `Invalid car image file type. Allowed types: ${allowedMimeTypes}`,
size: `Invalid car image file size. Limit is ${sizeLimitInMegaBytes}MB`
}
},
washingBegin: {
required: 'Begin time of washing is required',
invalid: 'Invalid begin time of washing'
@@ -248,4 +260,58 @@ router.delete('/:id', async (req, res, next) => {
}
})
const storage = multer.memoryStorage()
const upload = multer({
storage: storage,
limits: { fileSize: sizeLimitInMegaBytes * 1024 * 1024 },
fileFilter: (req, file, cb) => {
if (allowedMimeTypes.includes(file.mimetype)) {
cb(null, true)
} else {
cb(new Error(VALIDATION_MESSAGES.carImg.invalid.type), false)
}
}
})
const convertFileToBase64 = (file) => {
const base64Image = file.buffer.toString('base64')
return base64Image
}
router.post('/:id/upload-car-img', upload.single('file'), async (req, res) => {
const { id: orderId } = req.params
if (!mongoose.Types.ObjectId.isValid(orderId)) {
throw new Error(VALIDATION_MESSAGES.orderId.invalid)
}
const order = await OrderModel.findById(orderId)
if (!order) {
throw new Error(VALIDATION_MESSAGES.order.notFound)
}
if (!req.file) {
throw new Error(VALIDATION_MESSAGES.carImg.required)
}
const orderCarImg = await OrderCarImgModel.create({
file: convertFileToBase64(req.file),
orderId,
created: new Date().toISOString(),
})
res.status(200).send({ success: true, body: orderCarImg })
})
router.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
switch (err.message) {
case 'File too large':
return res.status(400).json({ success: false, error: VALIDATION_MESSAGES.carImg.invalid.size })
default:
return res.status(400).json({ success: false, error: err.message })
}
}
throw new Error(err.message)
})
module.exports = router