Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/apis/reservations/dto/return-reservation.output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Field, ObjectType } from '@nestjs/graphql';
import { Review } from 'src/apis/reviews/entities/review.entity';
import { User } from 'src/apis/users/entities/user.entity';

@ObjectType()
export class returnUserWithReviewOutput {
@Field(() => User)
profile: User;

@Field(() => Review)
review: Review;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ export interface IReservationsServiceFindAllByUserId {
export interface IReservationsServiceFindAllByShopId {
shopId: string;
}

export interface IReservationsServiceFindForShopDetailPage {
shopId: string;
}
4 changes: 4 additions & 0 deletions src/apis/reservations/reservation.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DogsService } from '../dogs/dogs.service';
import { Dog } from '../dogs/entities/dog.entity';
import { Review } from '../reviews/entities/review.entity';
import { ReviewsService } from '../reviews/reviews.service';
import { Shop } from '../shops/entities/shop.entity';
import { ShopsService } from '../shops/shops.service';
import { User } from '../users/entities/user.entity';
Expand All @@ -14,6 +16,7 @@ import { ReservationsService } from './reservation.service';
imports: [
TypeOrmModule.forFeature([
Reservation, //
Review,
User,
Shop,
Dog,
Expand All @@ -22,6 +25,7 @@ import { ReservationsService } from './reservation.service';
providers: [
ReservationsResolver, //
ReservationsService,
ReviewsService,
ShopsService,
UsersService,
DogsService,
Expand Down
18 changes: 14 additions & 4 deletions src/apis/reservations/reservation.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
import { IContext } from 'src/commons/interface/context';
import { GqlAuthGuard } from '../auth/guards/gql-auth.guard';
import { CreateReservationInput } from './dto/create-reservation.input';
import { returnUserWithReviewOutput } from './dto/return-reservation.output';
import { Reservation } from './entities/reservation.entity';
import { ReservationsService } from './reservation.service';

Expand Down Expand Up @@ -51,11 +52,20 @@ export class ReservationsResolver {
description: 'Return : 한 가게의 예약 정보',
})
fetchReservationsByShop(
@Context() context: IContext, //
@Args('shopId') shopId: string, //
): Promise<Reservation[]> {
const userId = context.req.user.id;
console.log(userId, '@@@@');
return this.reservationsService.findAllByUserId({ userId });
return this.reservationsService.findAllByShopId({ shopId });
}

// 가게의 모든 예약과 예약자 가져오기
@Query(() => [returnUserWithReviewOutput], {
description:
'Return : { profile: 회원정보 , review: 그 회원이 작성한 리뷰 } 형식의 객체들이 모인 배열',
})
fetchForShopDetailPage(
@Args('shopId') shopId: string, //
): Promise<returnUserWithReviewOutput[]> {
return this.reservationsService.findForShopDetailPage({ shopId });
}

//예약 삭제하기
Expand Down
59 changes: 59 additions & 0 deletions src/apis/reservations/reservation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import {
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DogsService } from '../dogs/dogs.service';
import { Review } from '../reviews/entities/review.entity';
import { ReviewsService } from '../reviews/reviews.service';
import { ShopsService } from '../shops/shops.service';
import { User } from '../users/entities/user.entity';
import { UsersService } from '../users/user.service';
import { returnUserWithReviewOutput } from './dto/return-reservation.output';
import { Reservation } from './entities/reservation.entity';
import {
IReservationsServiceCheckDuplication,
Expand All @@ -17,6 +21,7 @@ import {
IReservationsServiceFindAllByUserId,
IReservationsServiceFindById,
IReservationsServiceFindDeletedById,
IReservationsServiceFindForShopDetailPage,
} from './interfaces/reservations-service.interface';

@Injectable()
Expand All @@ -27,6 +32,8 @@ export class ReservationsService {
private readonly usersService: UsersService,
private readonly shopsService: ShopsService,
private readonly dogsService: DogsService,
@InjectRepository(Review)
private readonly reviewsRepository: Repository<Review>,
) {}

// 신규 예약 정보 생성
Expand Down Expand Up @@ -150,6 +157,58 @@ export class ReservationsService {
return result;
}

// 가게 상세페이지용 : 가게의 모든 리뷰작성자 프로필과 리뷰 가져오기
async findForShopDetailPage({
shopId,
}: IReservationsServiceFindForShopDetailPage): Promise<
returnUserWithReviewOutput[]
> {
// 해당 가게의 예약들
const myBooks = await this.reservationsRepository.find({
where: { shop: { id: shopId } },
relations: ['shop', 'user'],
});
// 예약과 연결된 유저ID들
const userIds = [];
const userIds1 = myBooks.forEach((el) => {
if (!userIds.includes(el.user.id)) {
userIds.push(el.user.id);
}
});

// 예약의 리뷰들
const myReviews: Review[] = [];
for (let i = 0; i < myBooks.length; i++) {
const reviews = await this.reviewsRepository.find({
where: { shop: { id: shopId }, reservation: { id: myBooks[i].id } },
relations: ['shop', 'reservation'],
});
if (reviews[0] !== undefined) {
myReviews.push(reviews[0]);
}
}

const fetchList: returnUserWithReviewOutput[] = [];
// 유저-리뷰 매핑 // 가독성을 위해 우선 for문 사용
for (let i = 0; i < userIds.length; i++) {
for (let j = 0; j < myReviews.length; j++) {
const resultBook = await this.reservationsRepository.find({
where: {
shop: { id: shopId },
user: { id: userIds[i] },
},
relations: ['user'],
});
const _user = resultBook[0].user;
const _review = myReviews[j];
if (resultBook[0].id === myReviews[0].reservation.id)
fetchList.push({ profile: _user, review: _review });
}
}

return fetchList;
}

//예약 삭제하기
async delete({
reservationId,
Expand Down
35 changes: 35 additions & 0 deletions src/apis/reviews/__test__/reviews.resolver.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Test, TestingModule } from '@nestjs/testing';
import { Review } from '../entities/review.entity';
import { ReviewsResolver } from '../reviews.resolver';
import { ReviewsService } from '../reviews.service';

jest.mock('../reviews.service');

const EXAMPLE_REVIEW: Review = {
//
};

describe('ReviewResolver', () => {
let mockReviewsService: ReviewsService;
let reviewsResolver: ReviewsResolver;

beforeEach(async () => {
const reviewsModule: TestingModule = await Test.createTestingModule({
providers: [
ReviewsResolver,
{
provide: ReviewsService,
useValue: mockReviewsService,
},
],
}).compile();
mockReviewsService = reviewsModule.get<ReviewsService>(ReviewsService);
reviewsResolver = reviewsResolver.get<ReviewsResolver>(ReviewsResolver);
});

describe('fetchReview', () => {
it('reivewService의 find 메서드 실행', async () => {
await reviewsResolver.fetchReview({ reviewId });
});
});
});
2 changes: 1 addition & 1 deletion src/apis/reviews/entities/review.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class Review {

@CreateDateColumn({ nullable: true })
@Field(() => Date)
createAt: Date;
createdAt: Date;

@Column()
@Field(() => Float)
Expand Down
1 change: 1 addition & 0 deletions src/apis/reviews/interfaces/reviews-service.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export interface IReviewServiceFindByUserId {
export interface IReviewServiceFindByShopId {
shopId: string;
page: number;
count: number;
}
8 changes: 7 additions & 1 deletion src/apis/reviews/reviews.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,16 @@ export class ReviewsResolver {
async fetchReviewsByShopId(
@Args({ name: 'page', defaultValue: 1, nullable: true })
page: number, //
@Args({ name: 'page', defaultValue: 1, nullable: true })
count: number, //
@Args('shopId')
shopId: string, //
): Promise<Review[]> {
return await this.reviewsService.findByShopId({ page, shopId });
return await this.reviewsService.findByShopIdWithPage({
page,
count,
shopId,
});
}

@UseGuards(GqlAuthGuard('access'))
Expand Down
14 changes: 8 additions & 6 deletions src/apis/reviews/reviews.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,25 @@ export class ReviewsService {
}

// 가게의 모든 리뷰 가져오기
async findByShopId({
async findByShopIdWithPage({
page,
shopId, //
count, //
shopId,
}: IReviewServiceFindByShopId): Promise<Review[]> {
const checkShop = await this.shopsService.findById({ shopId });
if (!checkShop) {
throw new UnprocessableEntityException('유효하지 않은 가게ID 입니다');
}
const result = await this.reviewsRepository.find({
where: { shop: { id: shopId } },
skip: (page - 1) * 4,
take: 4,
skip: (page - 1) * count,
take: count,
order: {
createAt: 'ASC',
createdAt: 'ASC',
},
relations: ['shop', 'reservation'],
});
console.log(result);

return result;
}

Expand Down