up
This commit is contained in:
@@ -14,6 +14,7 @@ import { UploaderModule } from './modules/uploader/uploader.module';
|
||||
import { AdminModule } from './modules/admin/admin.module';
|
||||
// import { CacheService } from './modules/utils/cache.service';
|
||||
import { ThrottlerModule } from '@nestjs/throttler';
|
||||
import { RestaurantsModule } from './modules/restaurants/restaurants.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -41,6 +42,7 @@ import { ThrottlerModule } from '@nestjs/throttler';
|
||||
limit: 5, // max requests per window
|
||||
},
|
||||
]),
|
||||
RestaurantsModule,
|
||||
],
|
||||
controllers: [],
|
||||
// providers: [CacheService],
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
import { IsString, IsOptional, IsNumber, IsBoolean, IsArray, IsUrl } from 'class-validator';
|
||||
|
||||
export class CreateRestaurantDto {
|
||||
@ApiProperty({ example: 'Cafe Morteza' })
|
||||
@IsString()
|
||||
name!: string;
|
||||
|
||||
@ApiProperty({ example: 'cafe-morteza' })
|
||||
@IsString()
|
||||
slug!: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'https://example.com/logo.png' })
|
||||
@IsOptional()
|
||||
@IsUrl()
|
||||
logo?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'Tehran, Valiasr St. No. 123' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
address?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: '#ff6600' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
menuColor?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 35.6892 })
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
latitude?: number;
|
||||
|
||||
@ApiPropertyOptional({ example: 51.389 })
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
longitude?: number;
|
||||
|
||||
@ApiPropertyOptional({ example: 5000, description: 'Service area in meters' })
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
serviceArea?: number;
|
||||
|
||||
@ApiPropertyOptional({ example: 2020 })
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
establishedYear?: number;
|
||||
|
||||
@ApiPropertyOptional({ example: '+989123456789' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
phoneNumber?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'https://instagram.com/cafemorteza' })
|
||||
@IsOptional()
|
||||
@IsUrl()
|
||||
instagram?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'https://t.me/cafemorteza' })
|
||||
@IsOptional()
|
||||
@IsUrl()
|
||||
telegram?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'https://wa.me/989123456789' })
|
||||
@IsOptional()
|
||||
@IsUrl()
|
||||
whatsapp?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'Cozy place with best coffee in town.' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'Best Cafe in Tehran' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
seoTitle?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: 'Cafe Morteza serves high-quality coffee.' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
seoDescription?: string;
|
||||
|
||||
@ApiPropertyOptional({ example: ['coffee', 'breakfast', 'cafe'] })
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
tagNames?: string[];
|
||||
|
||||
@ApiPropertyOptional({ example: true })
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
isOpenNow?: boolean;
|
||||
|
||||
@ApiPropertyOptional({ example: 0.09 })
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
vat?: number;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { PartialType } from '@nestjs/swagger';
|
||||
import { CreateRestaurantDto } from './create-restaurant.dto';
|
||||
|
||||
export class UpdateRestaurantDto extends PartialType(CreateRestaurantDto) {}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { Entity, Property } from '@mikro-orm/core';
|
||||
import { BaseEntity } from '../../../common/entities/base.entity';
|
||||
|
||||
@Entity({ tableName: 'restaurants' })
|
||||
export class Restaurant extends BaseEntity {
|
||||
// --- اطلاعات پایه ---
|
||||
@Property()
|
||||
name!: string;
|
||||
|
||||
@Property({ unique: true })
|
||||
slug!: string;
|
||||
|
||||
@Property({ nullable: true })
|
||||
logo?: string;
|
||||
|
||||
@Property({ nullable: true })
|
||||
address?: string;
|
||||
|
||||
@Property({ nullable: true })
|
||||
menuColor?: string;
|
||||
|
||||
// --- مختصات جغرافیایی ---
|
||||
@Property({ nullable: true })
|
||||
latitude?: number;
|
||||
|
||||
@Property({ nullable: true })
|
||||
longitude?: number;
|
||||
|
||||
// --- شعاع خدمات (مثلاً بر حسب متر یا کیلومتر) ---
|
||||
@Property({ nullable: true })
|
||||
serviceArea?: number;
|
||||
|
||||
// --- وضعیتها ---
|
||||
@Property({ default: true })
|
||||
isActive: boolean = true;
|
||||
|
||||
@Property({ nullable: true })
|
||||
establishedYear?: number;
|
||||
|
||||
@Property({ nullable: true })
|
||||
phoneNumber?: string;
|
||||
|
||||
@Property({ nullable: true })
|
||||
instagram?: string;
|
||||
|
||||
@Property({ nullable: true })
|
||||
telegram?: string;
|
||||
|
||||
@Property({ nullable: true })
|
||||
whatsapp?: string;
|
||||
|
||||
// --- توضیحات ---
|
||||
@Property({ type: 'text', nullable: true })
|
||||
description?: string;
|
||||
|
||||
// --- سئو ---
|
||||
@Property({ nullable: true })
|
||||
seoTitle?: string;
|
||||
|
||||
@Property({ nullable: true, type: 'text' })
|
||||
seoDescription?: string;
|
||||
|
||||
@Property({ nullable: true, type: 'json' })
|
||||
tagNames?: string[];
|
||||
|
||||
// --- مالیات یا VAT ---
|
||||
@Property({ type: 'decimal', default: 0 })
|
||||
vat?: number = 0;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
||||
import { RestaurantsService } from './restaurants.service';
|
||||
import { CreateRestaurantDto } from './dto/create-restaurant.dto';
|
||||
import { UpdateRestaurantDto } from './dto/update-restaurant.dto';
|
||||
|
||||
@Controller('restaurants')
|
||||
export class RestaurantsController {
|
||||
constructor(private readonly restaurantsService: RestaurantsService) {}
|
||||
|
||||
@Post()
|
||||
create(@Body() createRestaurantDto: CreateRestaurantDto) {
|
||||
return this.restaurantsService.create(createRestaurantDto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.restaurantsService.findAll();
|
||||
}
|
||||
|
||||
@Get(':slug')
|
||||
findOne(@Param('slug') slug: string) {
|
||||
return this.restaurantsService.findBySlug(slug);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
update(@Param('id') id: string, @Body() updateRestaurantDto: UpdateRestaurantDto) {
|
||||
return this.restaurantsService.update(+id, updateRestaurantDto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
remove(@Param('id') id: string) {
|
||||
return this.restaurantsService.remove(+id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { RestaurantsService } from './restaurants.service';
|
||||
import { RestaurantsController } from './restaurants.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [RestaurantsController],
|
||||
providers: [RestaurantsService],
|
||||
})
|
||||
export class RestaurantsModule {}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { CreateRestaurantDto } from './dto/create-restaurant.dto';
|
||||
import { UpdateRestaurantDto } from './dto/update-restaurant.dto';
|
||||
import { Restaurant } from './entities/restaurant.entity';
|
||||
import { EntityManager } from '@mikro-orm/postgresql';
|
||||
|
||||
@Injectable()
|
||||
export class RestaurantsService {
|
||||
constructor(private readonly em: EntityManager) {}
|
||||
|
||||
async create(dto: CreateRestaurantDto): Promise<Restaurant> {
|
||||
const restaurant = this.em.create(Restaurant, {
|
||||
...dto,
|
||||
isActive: true,
|
||||
});
|
||||
|
||||
await this.em.persistAndFlush(restaurant);
|
||||
return restaurant;
|
||||
}
|
||||
|
||||
findAll() {
|
||||
return `This action returns all restaurants`;
|
||||
}
|
||||
|
||||
async findBySlug(slug: string): Promise<Restaurant> {
|
||||
const restaurant = await this.em.findOne(Restaurant, { slug });
|
||||
|
||||
if (!restaurant) {
|
||||
throw new NotFoundException(`Restaurant with slug "${slug}" not found`);
|
||||
}
|
||||
|
||||
return restaurant;
|
||||
}
|
||||
|
||||
update(id: number, updateRestaurantDto: UpdateRestaurantDto) {
|
||||
return `This action updates a #${id} restaurant`;
|
||||
}
|
||||
|
||||
remove(id: number) {
|
||||
return `This action removes a #${id} restaurant`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user