Доработка методов, userId в токене, инфа в сваггере
This commit is contained in:
parent
7895352e76
commit
81a5a829a9
|
|
@ -24,9 +24,13 @@ export class AuthService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(user: { email: string; password: string }) {
|
login(user: Omit<User, 'password'>) {
|
||||||
this.logger.log('LOG');
|
this.logger.log('LOG');
|
||||||
const payload = { username: user.email, sub: user.password };
|
const payload = {
|
||||||
|
username: user.email,
|
||||||
|
sub: user.userId,
|
||||||
|
userId: user.userId,
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
access_token: this.jwtService.sign(payload),
|
access_token: this.jwtService.sign(payload),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Controller, Get, Query, Param } from '@nestjs/common';
|
import { Controller, Get, Query, Param, Post, Body, HttpCode, HttpStatus } from '@nestjs/common';
|
||||||
import { CatalogService } from './catalog.service';
|
import { CatalogService } from './catalog.service';
|
||||||
import { CatalogResponseDto } from './dto/catalog-response.dto';
|
import { CatalogResponseDto } from './dto/catalog-response.dto';
|
||||||
import { CatalogFiltersDto } from './dto/catalog-filters.dto';
|
import { CatalogFiltersDto } from './dto/catalog-filters.dto';
|
||||||
|
|
@ -11,9 +11,13 @@ import {
|
||||||
ApiResponse,
|
ApiResponse,
|
||||||
ApiOperation,
|
ApiOperation,
|
||||||
ApiProperty,
|
ApiProperty,
|
||||||
|
ApiBody,
|
||||||
|
ApiTags,
|
||||||
} from '@nestjs/swagger';
|
} from '@nestjs/swagger';
|
||||||
import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto';
|
import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto';
|
||||||
|
import { CreateYachtDto } from './dto/create-yacht.dto';
|
||||||
|
|
||||||
|
@ApiTags('catalog')
|
||||||
@Controller('catalog')
|
@Controller('catalog')
|
||||||
export class CatalogController {
|
export class CatalogController {
|
||||||
constructor(private readonly catalogService: CatalogService) {}
|
constructor(private readonly catalogService: CatalogService) {}
|
||||||
|
|
@ -64,6 +68,19 @@ export class CatalogController {
|
||||||
return this.catalogService.getMainPageCatalog();
|
return this.catalogService.getMainPageCatalog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('user/:userId')
|
||||||
|
@ApiOperation({ summary: 'Get catalog items by user ID' })
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'Catalog items for the specified user',
|
||||||
|
type: [CatalogItemShortDto],
|
||||||
|
})
|
||||||
|
async getCatalogByUserId(
|
||||||
|
@Param('userId') userId: string,
|
||||||
|
): Promise<CatalogItemShortDto[]> {
|
||||||
|
return this.catalogService.getCatalogByUserId(Number(userId));
|
||||||
|
}
|
||||||
|
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
@ApiOperation({ summary: 'Get catalog item by ID with full details' })
|
@ApiOperation({ summary: 'Get catalog item by ID with full details' })
|
||||||
@ApiResponse({
|
@ApiResponse({
|
||||||
|
|
@ -76,4 +93,21 @@ export class CatalogController {
|
||||||
): Promise<CatalogItemLongDto | null> {
|
): Promise<CatalogItemLongDto | null> {
|
||||||
return this.catalogService.getCatalogItemById(Number(id));
|
return this.catalogService.getCatalogItemById(Number(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
@HttpCode(HttpStatus.CREATED)
|
||||||
|
@ApiOperation({ summary: 'Create a new yacht in catalog' })
|
||||||
|
@ApiBody({ type: CreateYachtDto })
|
||||||
|
@ApiResponse({
|
||||||
|
status: 201,
|
||||||
|
description: 'Yacht successfully created',
|
||||||
|
type: CatalogItemLongDto,
|
||||||
|
})
|
||||||
|
@ApiResponse({
|
||||||
|
status: 400,
|
||||||
|
description: 'Bad request',
|
||||||
|
})
|
||||||
|
async createYacht(@Body() createYachtDto: CreateYachtDto): Promise<CatalogItemLongDto> {
|
||||||
|
return this.catalogService.createYacht(createYachtDto);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Module } from '@nestjs/common';
|
import { Module, forwardRef } from '@nestjs/common';
|
||||||
import { CatalogService } from './catalog.service';
|
import { CatalogService } from './catalog.service';
|
||||||
import { CatalogController } from './catalog.controller';
|
import { CatalogController } from './catalog.controller';
|
||||||
import { UsersModule } from '../users/users.module';
|
import { UsersModule } from '../users/users.module';
|
||||||
|
|
@ -8,10 +8,11 @@ import { ReviewsModule } from '../reviews/reviews.module';
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
UsersModule, // This provides UsersService
|
UsersModule, // This provides UsersService
|
||||||
ReservationsModule, // This provides ReservationsService
|
forwardRef(() => ReservationsModule), // This provides ReservationsService
|
||||||
ReviewsModule, // This provides ReviewsService
|
ReviewsModule, // This provides ReviewsService
|
||||||
],
|
],
|
||||||
controllers: [CatalogController],
|
controllers: [CatalogController],
|
||||||
providers: [CatalogService],
|
providers: [CatalogService],
|
||||||
|
exports: [CatalogService], // Export for other modules to use
|
||||||
})
|
})
|
||||||
export class CatalogModule {}
|
export class CatalogModule {}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable, Inject, forwardRef } from '@nestjs/common';
|
||||||
import { UsersService } from '../users/users.service';
|
import { UsersService } from '../users/users.service';
|
||||||
import { ReservationsService } from '../reservations/reservations.service';
|
import { ReservationsService } from '../reservations/reservations.service';
|
||||||
import { ReviewsService } from '../reviews/reviews.service';
|
import { ReviewsService } from '../reviews/reviews.service';
|
||||||
|
|
@ -10,11 +10,13 @@ import { CatalogParamsDto } from './dto/catalog-params.dto';
|
||||||
import { CatalogResponseDto } from './dto/catalog-response.dto';
|
import { CatalogResponseDto } from './dto/catalog-response.dto';
|
||||||
import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto';
|
import { MainPageCatalogResponseDto } from './dto/main-page-catalog-response.dto';
|
||||||
import { CatalogFiltersDto } from './dto/catalog-filters.dto';
|
import { CatalogFiltersDto } from './dto/catalog-filters.dto';
|
||||||
|
import { CreateYachtDto } from './dto/create-yacht.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CatalogService {
|
export class CatalogService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly usersService: UsersService,
|
private readonly usersService: UsersService,
|
||||||
|
@Inject(forwardRef(() => ReservationsService))
|
||||||
private readonly reservationsService: ReservationsService,
|
private readonly reservationsService: ReservationsService,
|
||||||
private readonly reviewsService: ReviewsService,
|
private readonly reviewsService: ReviewsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
@ -49,7 +51,7 @@ export class CatalogService {
|
||||||
power: 1200,
|
power: 1200,
|
||||||
description:
|
description:
|
||||||
'Роскошная моторная яхта Азимут 55 - это воплощение итальянского стиля и российского качества. Идеально подходит для прогулок по Финскому заливу, корпоративных мероприятий и романтических свиданий. На борту: три комфортабельные каюты, просторный салон с панорамным остеклением, полностью оборудованная кухня и две ванные комнаты. Максимальная скорость 32 узла позволяет быстро добраться до самых живописных мест Карельского перешейка.',
|
'Роскошная моторная яхта Азимут 55 - это воплощение итальянского стиля и российского качества. Идеально подходит для прогулок по Финскому заливу, корпоративных мероприятий и романтических свиданий. На борту: три комфортабельные каюты, просторный салон с панорамным остеклением, полностью оборудованная кухня и две ванные комнаты. Максимальная скорость 32 узла позволяет быстро добраться до самых живописных мест Карельского перешейка.',
|
||||||
owner: null as any,
|
owner: { userId: 1 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -83,7 +85,7 @@ export class CatalogService {
|
||||||
power: 1400,
|
power: 1400,
|
||||||
description:
|
description:
|
||||||
'Британский шик и русская душа в одной яхте! Сансикер Манхэттен 52 - выбор настоящих ценителей морских путешествий. Просторный кокпит с мягкими диванами, бар на 8 персон, система мультимедиа премиум-класса. Идеальна для празднования дня рождения на воде или деловой встречи с партнерами. Отличная маневренность позволяет заходить в марины Санкт-Петербурга и Кронштадта.',
|
'Британский шик и русская душа в одной яхте! Сансикер Манхэттен 52 - выбор настоящих ценителей морских путешествий. Просторный кокпит с мягкими диванами, бар на 8 персон, система мультимедиа премиум-класса. Идеальна для празднования дня рождения на воде или деловой встречи с партнерами. Отличная маневренность позволяет заходить в марины Санкт-Петербурга и Кронштадта.',
|
||||||
owner: null as any,
|
owner: { userId: 2 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -117,7 +119,7 @@ export class CatalogService {
|
||||||
power: 1100,
|
power: 1100,
|
||||||
description:
|
description:
|
||||||
'Принцесс V55 - королева российских вод! Эта яхта создана для тех, кто ценит комфорт и элегантность. Четыре уютные каюты с кондиционером, гальюн с душем, полностью оборудованная камбузная зона. Особенность - огромный платц с гидравлическим трапом для купания в Ладожском озере. Отличный выбор для семейного отдыха или рыбалки с друзьями.',
|
'Принцесс V55 - королева российских вод! Эта яхта создана для тех, кто ценит комфорт и элегантность. Четыре уютные каюты с кондиционером, гальюн с душем, полностью оборудованная камбузная зона. Особенность - огромный платц с гидравлическим трапом для купания в Ладожском озере. Отличный выбор для семейного отдыха или рыбалки с друзьями.',
|
||||||
owner: null as any,
|
owner: { userId: 1 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -151,7 +153,7 @@ export class CatalogService {
|
||||||
power: 900,
|
power: 900,
|
||||||
description:
|
description:
|
||||||
'Итальянская страсть в русской стихии! Ферретти 500 сочетает в себе средиземноморский шарм и надежность для суровых условий Балтики. Просторный салон с панорамными окнами, обеденная зона на 6 человек, современная навигационная система. Идеально подходит для фотосессий на фоне разводных мостов Петербурга или романтического ужина под звуки волн.',
|
'Итальянская страсть в русской стихии! Ферретти 500 сочетает в себе средиземноморский шарм и надежность для суровых условий Балтики. Просторный салон с панорамными окнами, обеденная зона на 6 человек, современная навигационная система. Идеально подходит для фотосессий на фоне разводных мостов Петербурга или романтического ужина под звуки волн.',
|
||||||
owner: null as any,
|
owner: { userId: 2 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -184,7 +186,7 @@ export class CatalogService {
|
||||||
power: 1300,
|
power: 1300,
|
||||||
description:
|
description:
|
||||||
'Американская мощь для русского моря! Си Рей 510 Сандансер - самая быстрая яхта в нашем флоте. Развивает скорость до 35 узлов, что позволяет за день обогнуть весь Финский залив. Три комфортабельные каюты, система стабилизации на стоянке, мощная аудиосистема с сабвуфером. Отличный выбор для любителей острых ощущений и скоростных прогулок.',
|
'Американская мощь для русского моря! Си Рей 510 Сандансер - самая быстрая яхта в нашем флоте. Развивает скорость до 35 узлов, что позволяет за день обогнуть весь Финский залив. Три комфортабельные каюты, система стабилизации на стоянке, мощная аудиосистема с сабвуфером. Отличный выбор для любителей острых ощущений и скоростных прогулок.',
|
||||||
owner: null as any,
|
owner: { userId: 1 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -217,7 +219,7 @@ export class CatalogService {
|
||||||
power: 320,
|
power: 320,
|
||||||
description:
|
description:
|
||||||
'Немецкое качество для русского характера! Бавария SR41 - надежная и экономичная яхта для спокойных прогулок по Ладоге. Две уютные каюты, просторный кокпит с тентом от дождя, лебедка для подъема парусов. Идеальный выбор для начинающих яхтсменов или семейного отдыха с детьми. Расход топлива всего 15 литров в час!',
|
'Немецкое качество для русского характера! Бавария SR41 - надежная и экономичная яхта для спокойных прогулок по Ладоге. Две уютные каюты, просторный кокпит с тентом от дождя, лебедка для подъема парусов. Идеальный выбор для начинающих яхтсменов или семейного отдыха с детьми. Расход топлива всего 15 литров в час!',
|
||||||
owner: null as any,
|
owner: { userId: 2 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -250,7 +252,7 @@ export class CatalogService {
|
||||||
power: 250,
|
power: 250,
|
||||||
description:
|
description:
|
||||||
'Французская элегантность для русского простора! Жанно Мери Фишер 895 - компактная, но вместительная яхта для рыбалки и пикников. Одна просторная каюта, открытый кокпит, столик для барбекю. Отлично подходит для выездов на природу, ночевки в бухтах или обучения детей управлению яхтой. Самый экономичный вариант в нашем флоте!',
|
'Французская элегантность для русского простора! Жанно Мери Фишер 895 - компактная, но вместительная яхта для рыбалки и пикников. Одна просторная каюта, открытый кокпит, столик для барбекю. Отлично подходит для выездов на природу, ночевки в бухтах или обучения детей управлению яхтой. Самый экономичный вариант в нашем флоте!',
|
||||||
owner: null as any,
|
owner: { userId: 1 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -283,7 +285,7 @@ export class CatalogService {
|
||||||
power: 425,
|
power: 425,
|
||||||
description:
|
description:
|
||||||
'Французский траулер для русского севера! Бенето Свифт Троулер 41 создан для длительных путешествий по Белому морю. Экономичный дизельный двигатель, большой запас топлива, система опреснения воды. Две комфортабельные каюты с подогревом пола. Идеальный выбор для экспедиций или многодневных круизов по северным островам.',
|
'Французский траулер для русского севера! Бенето Свифт Троулер 41 создан для длительных путешествий по Белому морю. Экономичный дизельный двигатель, большой запас топлива, система опреснения воды. Две комфортабельные каюты с подогревом пола. Идеальный выбор для экспедиций или многодневных круизов по северным островам.',
|
||||||
owner: null as any,
|
owner: { userId: 2 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -316,7 +318,7 @@ export class CatalogService {
|
||||||
power: 90,
|
power: 90,
|
||||||
description:
|
description:
|
||||||
'Французский катамаран для русского размаха! Лагун 450 - невероятно устойчивая и просторная яхта. Четыре отдельные каюты с санузлами, огромный салон-трансформер, две кухни. Идеально подходит для больших компаний, свадебных церемоний на воде или длительных круизов всей семьей. Не кренится даже в шторм!',
|
'Французский катамаран для русского размаха! Лагун 450 - невероятно устойчивая и просторная яхта. Четыре отдельные каюты с санузлами, огромный салон-трансформер, две кухни. Идеально подходит для больших компаний, свадебных церемоний на воде или длительных круизов всей семьей. Не кренится даже в шторм!',
|
||||||
owner: null as any,
|
owner: { userId: 1 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -349,7 +351,7 @@ export class CatalogService {
|
||||||
power: 80,
|
power: 80,
|
||||||
description:
|
description:
|
||||||
'Французский катамаран класса люкс! Фонтен Пажо Люсия 40 - это плавающий пятизвездочный отель. Четыре каюты-люкс с джакузи, салон с камином, профессиональная кухня с шеф-поваром. Система стабилизации на якоре, гидромассажный бассейн на палубе. Выбор настоящих ценителей роскоши и комфорта на воде.',
|
'Французский катамаран класса люкс! Фонтен Пажо Люсия 40 - это плавающий пятизвездочный отель. Четыре каюты-люкс с джакузи, салон с камином, профессиональная кухня с шеф-поваром. Система стабилизации на якоре, гидромассажный бассейн на палубе. Выбор настоящих ценителей роскоши и комфорта на воде.',
|
||||||
owner: null as any,
|
owner: { userId: 2 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -382,7 +384,7 @@ export class CatalogService {
|
||||||
power: 380,
|
power: 380,
|
||||||
description:
|
description:
|
||||||
'Французская парусная яхта для русского ветра! Дюфур 460 - мечта любого яхтсмена. Три просторные каюты, кокпит с мягкими сиденьями, современное парусное вооружение. Идеально сбалансированная, легко управляется даже новичками. Отличный выбор для регат, обучения парусному спорту или романтических круизов под парусами.',
|
'Французская парусная яхта для русского ветра! Дюфур 460 - мечта любого яхтсмена. Три просторные каюты, кокпит с мягкими сиденьями, современное парусное вооружение. Идеально сбалансированная, легко управляется даже новичками. Отличный выбор для регат, обучения парусному спорту или романтических круизов под парусами.',
|
||||||
owner: null as any,
|
owner: { userId: 1 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -415,7 +417,7 @@ export class CatalogService {
|
||||||
power: 1600,
|
power: 1600,
|
||||||
description:
|
description:
|
||||||
'Американская легенда для русского океана! Гранд Бэнкс 60 - экспедиционная яхта для самых смелых путешествий. Три каюты-люкс, салон с библиотекой, зимний сад, сауна. Автономность плавания - 30 дней! Способна пересечь Баренцево море и дойти до Шпицбергена. Выбор для настоящих морских волков и исследователей Арктики.',
|
'Американская легенда для русского океана! Гранд Бэнкс 60 - экспедиционная яхта для самых смелых путешествий. Три каюты-люкс, салон с библиотекой, зимний сад, сауна. Автономность плавания - 30 дней! Способна пересечь Баренцево море и дойти до Шпицбергена. Выбор для настоящих морских волков и исследователей Арктики.',
|
||||||
owner: null as any,
|
owner: { userId: 2 } as any,
|
||||||
reviews: [],
|
reviews: [],
|
||||||
reservations: [],
|
reservations: [],
|
||||||
},
|
},
|
||||||
|
|
@ -610,4 +612,44 @@ export class CatalogService {
|
||||||
async getAllCatalogItems(): Promise<CatalogItemShortDto[]> {
|
async getAllCatalogItems(): Promise<CatalogItemShortDto[]> {
|
||||||
return this.catalogItems.map((item) => this.toShortDto(item));
|
return this.catalogItems.map((item) => this.toShortDto(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getCatalogByUserId(userId: number): Promise<CatalogItemShortDto[]> {
|
||||||
|
// Логика определения ownerId: нечетные id -> ownerId=1, четные id -> ownerId=2
|
||||||
|
const filteredItems = this.catalogItems.filter((item) => {
|
||||||
|
return item.owner?.userId === userId;
|
||||||
|
});
|
||||||
|
return filteredItems.map((item) => this.toShortDto(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
async createYacht(createYachtDto: CreateYachtDto): Promise<CatalogItemLongDto> {
|
||||||
|
const newId = Math.max(...this.catalogItems.map((item) => item.id || 0), 0) + 1;
|
||||||
|
const owner = await this.usersService.findById(createYachtDto.userId);
|
||||||
|
|
||||||
|
const newYacht: CatalogItemLongDto = {
|
||||||
|
id: newId,
|
||||||
|
name: createYachtDto.name,
|
||||||
|
length: createYachtDto.length,
|
||||||
|
speed: createYachtDto.speed,
|
||||||
|
minCost: createYachtDto.minCost,
|
||||||
|
mainImageUrl: createYachtDto.mainImageUrl,
|
||||||
|
galleryUrls: createYachtDto.galleryUrls,
|
||||||
|
hasQuickRent: createYachtDto.hasQuickRent,
|
||||||
|
isFeatured: createYachtDto.isFeatured,
|
||||||
|
year: createYachtDto.year,
|
||||||
|
comfortCapacity: createYachtDto.comfortCapacity,
|
||||||
|
maxCapacity: createYachtDto.maxCapacity,
|
||||||
|
width: createYachtDto.width,
|
||||||
|
cabinsCount: createYachtDto.cabinsCount,
|
||||||
|
matherial: createYachtDto.matherial,
|
||||||
|
power: createYachtDto.power,
|
||||||
|
description: createYachtDto.description,
|
||||||
|
owner: owner || ({ userId: createYachtDto.userId } as any),
|
||||||
|
reviews: [],
|
||||||
|
reservations: [],
|
||||||
|
topText: createYachtDto.topText,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.catalogItems.push(newYacht);
|
||||||
|
return newYacht;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class CreateYachtDto {
|
||||||
|
@ApiProperty({ example: 'Азимут 55', description: 'Название яхты' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 16.7, description: 'Длина яхты в метрах' })
|
||||||
|
length: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 32, description: 'Скорость в узлах' })
|
||||||
|
speed: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 85000, description: 'Минимальная стоимость аренды' })
|
||||||
|
minCost: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
example: 'api/uploads/1765727362318-238005198.jpg',
|
||||||
|
description: 'URL главного изображения',
|
||||||
|
})
|
||||||
|
mainImageUrl: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: [String],
|
||||||
|
example: ['api/uploads/1765727362318-238005198.jpg'],
|
||||||
|
description: 'URL галереи изображений',
|
||||||
|
})
|
||||||
|
galleryUrls: string[];
|
||||||
|
|
||||||
|
@ApiProperty({ example: true, description: 'Доступна быстрая аренда' })
|
||||||
|
hasQuickRent: boolean;
|
||||||
|
|
||||||
|
@ApiProperty({ example: false, description: 'Рекомендуемая яхта' })
|
||||||
|
isFeatured: boolean;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 2022, description: 'Год выпуска' })
|
||||||
|
year: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 8, description: 'Комфортная вместимость' })
|
||||||
|
comfortCapacity: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 12, description: 'Максимальная вместимость' })
|
||||||
|
maxCapacity: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 4.8, description: 'Ширина в метрах' })
|
||||||
|
width: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 3, description: 'Количество кают' })
|
||||||
|
cabinsCount: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 'Стеклопластик', description: 'Материал корпуса' })
|
||||||
|
matherial: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 1200, description: 'Мощность двигателя' })
|
||||||
|
power: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
example: 'Роскошная моторная яхта...',
|
||||||
|
description: 'Описание яхты',
|
||||||
|
})
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 1, description: 'ID владельца яхты' })
|
||||||
|
userId: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
required: false,
|
||||||
|
example: '🔥 Лучшее предложение',
|
||||||
|
description: 'Текст для отображения сверху',
|
||||||
|
})
|
||||||
|
topText?: string;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,28 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { CatalogItemLongDto } from '../catalog/dto/catalog-item.dto';
|
||||||
|
|
||||||
export class ReservationItemDto {
|
export class ReservationItemDto {
|
||||||
|
@ApiProperty({ example: 1, description: 'ID яхты' })
|
||||||
yachtId: number;
|
yachtId: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 1, description: 'ID резерватора' })
|
||||||
reservatorId: number;
|
reservatorId: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 1733097600, description: 'Начало резервации (Unix timestamp в UTC)' })
|
||||||
startUtc: number;
|
startUtc: number;
|
||||||
|
|
||||||
|
@ApiProperty({ example: 1733133600, description: 'Конец резервации (Unix timestamp в UTC)' })
|
||||||
endUtc: number;
|
endUtc: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ReservationWithYachtDto extends ReservationItemDto {
|
||||||
|
@ApiProperty({ example: 1, description: 'ID резервации' })
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: CatalogItemLongDto,
|
||||||
|
required: false,
|
||||||
|
description: 'Данные о яхте',
|
||||||
|
})
|
||||||
|
yacht?: CatalogItemLongDto;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,29 @@
|
||||||
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
|
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
|
||||||
|
import { ApiOperation, ApiResponse, ApiBody, ApiParam } from '@nestjs/swagger';
|
||||||
import { ReservationsService } from './reservations.service';
|
import { ReservationsService } from './reservations.service';
|
||||||
import { ReservationItemDto } from './reservation-item.dto';
|
import { ReservationItemDto, ReservationWithYachtDto } from './reservation-item.dto';
|
||||||
|
|
||||||
@Controller('reservations')
|
@Controller('reservations')
|
||||||
export class ReservationsController {
|
export class ReservationsController {
|
||||||
constructor(private readonly reservationsService: ReservationsService) {}
|
constructor(private readonly reservationsService: ReservationsService) {}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
|
@ApiOperation({ summary: 'Создать новую резервацию' })
|
||||||
|
@ApiBody({ type: ReservationItemDto })
|
||||||
|
@ApiResponse({ status: 201, description: 'Резервация успешно создана' })
|
||||||
create(@Body() dto: ReservationItemDto) {
|
create(@Body() dto: ReservationItemDto) {
|
||||||
return this.reservationsService.createReservation(dto);
|
return this.reservationsService.createReservation(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('user/:userId')
|
@Get('user/:userId')
|
||||||
findByUserId(@Param('userId') userId: string) {
|
@ApiOperation({ summary: 'Получить резервации по ID пользователя' })
|
||||||
|
@ApiParam({ name: 'userId', description: 'ID пользователя', type: Number })
|
||||||
|
@ApiResponse({
|
||||||
|
status: 200,
|
||||||
|
description: 'Список резерваций пользователя с данными о яхтах',
|
||||||
|
type: [ReservationWithYachtDto],
|
||||||
|
})
|
||||||
|
async findByUserId(@Param('userId') userId: string) {
|
||||||
return this.reservationsService.getReservationsByUserId(Number(userId));
|
return this.reservationsService.getReservationsByUserId(Number(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import { Module } from '@nestjs/common';
|
import { Module, forwardRef } from '@nestjs/common';
|
||||||
import { ReservationsService } from './reservations.service';
|
import { ReservationsService } from './reservations.service';
|
||||||
import { ReservationsController } from './reservations.controller';
|
import { ReservationsController } from './reservations.controller';
|
||||||
|
import { CatalogModule } from '../catalog/catalog.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [forwardRef(() => CatalogModule)],
|
||||||
controllers: [ReservationsController],
|
controllers: [ReservationsController],
|
||||||
providers: [ReservationsService],
|
providers: [ReservationsService],
|
||||||
exports: [ReservationsService], // Export for other modules to use
|
exports: [ReservationsService], // Export for other modules to use
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,23 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable, Inject, forwardRef } from '@nestjs/common';
|
||||||
import { ReservationItemDto } from './reservation-item.dto';
|
import { ReservationItemDto } from './reservation-item.dto';
|
||||||
|
import { CatalogService } from '../catalog/catalog.service';
|
||||||
|
import { CatalogItemLongDto } from '../catalog/dto/catalog-item.dto';
|
||||||
|
|
||||||
export interface Reservation extends ReservationItemDto {
|
export interface Reservation extends ReservationItemDto {
|
||||||
id: number;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ReservationWithYacht extends Reservation {
|
||||||
|
yacht?: CatalogItemLongDto;
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ReservationsService {
|
export class ReservationsService {
|
||||||
|
constructor(
|
||||||
|
@Inject(forwardRef(() => CatalogService))
|
||||||
|
private readonly catalogService: CatalogService,
|
||||||
|
) {}
|
||||||
|
|
||||||
private reservations: Reservation[] = [
|
private reservations: Reservation[] = [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
|
@ -70,8 +81,21 @@ export class ReservationsService {
|
||||||
return reservation;
|
return reservation;
|
||||||
}
|
}
|
||||||
|
|
||||||
getReservationsByUserId(userId: number): Reservation[] {
|
async getReservationsByUserId(userId: number): Promise<ReservationWithYacht[]> {
|
||||||
return this.reservations.filter((r) => r.reservatorId === userId);
|
const reservations = this.reservations.filter((r) => r.reservatorId === userId);
|
||||||
|
|
||||||
|
// Populate данные по яхте для каждой резервации
|
||||||
|
const reservationsWithYacht = await Promise.all(
|
||||||
|
reservations.map(async (reservation) => {
|
||||||
|
const yacht = await this.catalogService.getCatalogItemById(reservation.yachtId);
|
||||||
|
return {
|
||||||
|
...reservation,
|
||||||
|
yacht: yacht || undefined,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return reservationsWithYacht;
|
||||||
}
|
}
|
||||||
|
|
||||||
getReservationsByYachtId(yachtId: number): Reservation[] {
|
getReservationsByYachtId(yachtId: number): Reservation[] {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue