update license structures and setup file storage services

This commit is contained in:
2026-04-16 22:19:20 +03:30
parent d098ef10e1
commit ca494ee82a
75 changed files with 4550 additions and 1255 deletions
@@ -0,0 +1,12 @@
import { UploadedFileTypes } from '@/common/enums/enums'
import { ApiProperty } from '@nestjs/swagger'
import { IsEnum } from 'class-validator'
export class UploadImageDto {
@ApiProperty({
enum: UploadedFileTypes,
example: UploadedFileTypes.GOOD,
})
@IsEnum(UploadedFileTypes)
type: UploadedFileTypes
}
@@ -0,0 +1,11 @@
import { Injectable } from '@nestjs/common'
import { UploaderService } from './uploader.service'
@Injectable()
export class ImageUploaderService {
constructor(private readonly uploaderService: UploaderService) {}
async uploadImage(file: Express.Multer.File, type: '') {
// return this.uploaderService.uploadFile(file.buffer, file.originalname, type)
}
}
@@ -0,0 +1,45 @@
import { multerImageOptions } from '@/multer.config'
import {
BadRequestException,
Body,
Controller,
Post,
UploadedFile,
UseInterceptors,
} from '@nestjs/common'
import { FileInterceptor } from '@nestjs/platform-express'
import { ApiBody, ApiConsumes } from '@nestjs/swagger'
import { UploadImageDto } from './dto/image-upload.dto'
import { UploaderService } from './uploader.service'
@Controller('uploader')
export class UploaderController {
constructor(private readonly service: UploaderService) {}
@Post('image')
@UseInterceptors(FileInterceptor('file', multerImageOptions))
@ApiConsumes('multipart/form-data')
@ApiBody({
schema: {
type: 'object',
properties: {
file: { type: 'string', format: 'binary' },
type: {
type: 'string',
enum: ['avatar', 'banner', 'document', 'product'],
},
},
},
})
async uploadImage(
@UploadedFile() file: Express.Multer.File,
@Body() dto: UploadImageDto,
) {
if (!file) {
throw new BadRequestException('فایل را وارد کنید')
}
const url = await this.service.uploadFile(file, dto.type)
return { url }
}
}
@@ -0,0 +1,50 @@
import { checkAndDecodeJwtToken } from '@/common/utils/jwt-user.util'
import { PrismaService } from '@/prisma/prisma.service'
import { ForbiddenException, Injectable, NestMiddleware } from '@nestjs/common'
import { JwtService } from '@nestjs/jwt'
import { NextFunction, Request, Response } from 'express'
@Injectable()
export class PosMiddleware implements NestMiddleware {
constructor(
private prisma: PrismaService,
private jwtService: JwtService,
) {}
async use(req: Request, _res: Response, next: NextFunction) {
const doForbidden = () => {
throw new ForbiddenException('شما دسترسی لازم را ندارید')
}
try {
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
const { type, account_id } = tokenAccount!
if (type === 'ADMIN' || type === 'CONSUMER') {
const account = await this.prisma.account.findFirst({
where: {
OR: [
{
admin_account: {
id: account_id,
},
},
{
consumer_account: {
id: account_id,
},
},
],
},
})
if (account) return next()
}
throw doForbidden()
} catch (error) {
if (error && typeof error === 'object') {
throw error
}
return doForbidden()
}
}
}
+11
View File
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common'
import { StorageService } from '../storage/storage.service'
import { UploaderController } from './uploader.controller'
import { UploaderService } from './uploader.service'
@Module({
providers: [UploaderService, StorageService],
controllers: [UploaderController],
exports: [UploaderService],
})
export class UploaderModule {}
+33
View File
@@ -0,0 +1,33 @@
import { UploadedFileTypes } from '@/common/enums/enums'
import { Injectable } from '@nestjs/common'
import { StorageService } from '../storage/storage.service'
@Injectable()
export class UploaderService {
constructor(private readonly storageService: StorageService) {}
async uploadFile(file: Express.Multer.File, type: UploadedFileTypes) {
const uploaded = await this.storageService.uploadFile(file, type)
return uploaded
// await fs.mkdir(dirPath, { recursive: true })
// await fs.writeFile(filePath, buffer)
// Return a URL path, e.g. /uploads/{accountId}/{type}/{filename}
// return `/uploads/${type}/${filename}`
}
async deleteFile(url: string) {
const key = url?.split('/').pop()
if (key) {
return await this.storageService.deleteFile(key)
}
return {}
// await fs.mkdir(dirPath, { recursive: true })
// await fs.writeFile(filePath, buffer)
// Return a URL path, e.g. /uploads/{accountId}/{type}/{filename}
// return `/uploads/${type}/${filename}`
}
}