From 2b69d0e718fb565f6dace386f450d7bc65486896 Mon Sep 17 00:00:00 2001 From: saehun Date: Sun, 30 Jun 2024 04:03:40 +0900 Subject: [PATCH] impl --- src/app.module.ts | 2 + src/entities/index.ts | 17 +- src/entities/kakao-place.entity.ts | 14 ++ src/entities/place-for-map.entity.ts | 53 +++++ src/entities/place-for-map.repository.ts | 5 + src/entities/place.entity.ts | 46 ++++ src/entities/place.repository.ts | 5 + src/migrations/.snapshot-korrk-stage.json | 262 +++++++++++++++++++++- src/migrations/Migration20240629185552.ts | 68 ++++++ src/place/place.controller.ts | 90 ++++++++ src/place/place.module.ts | 18 ++ src/place/place.service.ts | 118 ++++++++++ src/search/search.module.ts | 1 + src/search/search.service.ts | 8 + 14 files changed, 705 insertions(+), 2 deletions(-) create mode 100644 src/entities/place-for-map.entity.ts create mode 100644 src/entities/place-for-map.repository.ts create mode 100644 src/entities/place.entity.ts create mode 100644 src/entities/place.repository.ts create mode 100644 src/migrations/Migration20240629185552.ts create mode 100644 src/place/place.controller.ts create mode 100644 src/place/place.module.ts create mode 100644 src/place/place.service.ts diff --git a/src/app.module.ts b/src/app.module.ts index 6998343..21d470f 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -11,6 +11,7 @@ import { AuthModule } from './auth/auth.module'; import { getNodeEnv, isIgnoreEnvFile } from './common/helper/env.helper'; import { envValidation } from './common/helper/env.validation'; import { MapModule } from './map/map.module'; +import { PlaceModule } from './place/place.module'; import { SearchModule } from './search/search.module'; import { UserMapModule } from './user-map/user-map.module'; import { UserModule } from './user/user.module'; @@ -30,6 +31,7 @@ import { UserModule } from './user/user.module'; MapModule, UserMapModule, SearchModule, + PlaceModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/entities/index.ts b/src/entities/index.ts index c9d7abc..86ab503 100644 --- a/src/entities/index.ts +++ b/src/entities/index.ts @@ -1,5 +1,7 @@ import { GroupMap } from './group-map.entity'; import { KakaoPlace } from './kakao-place.entity'; +import { PlaceForMap } from './place-for-map.entity'; +import { Place } from './place.entity'; import { UserMap } from './user-map.entity'; import { User } from './user.entity'; @@ -15,4 +17,17 @@ export * from './user.repository'; export * from './kakao-place.entity'; export * from './kakao-place.repository'; -export const entities = [User, GroupMap, UserMap, KakaoPlace]; +export * from './place-for-map.entity'; +export * from './place-for-map.repository'; + +export * from './place.entity'; +export * from './place.repository'; + +export const entities = [ + User, + GroupMap, + UserMap, + KakaoPlace, + Place, + PlaceForMap, +]; diff --git a/src/entities/kakao-place.entity.ts b/src/entities/kakao-place.entity.ts index 6948975..cf8f7c9 100644 --- a/src/entities/kakao-place.entity.ts +++ b/src/entities/kakao-place.entity.ts @@ -36,6 +36,20 @@ export class KakaoPlace { }) address: string; + @Property({ + type: 'number', + comment: '카카오맵 경도', + default: 0, + }) + x: number; + + @Property({ + type: 'number', + comment: '카카오맵 위도', + default: 0, + }) + y: number; + @Property({ type: 'json', comment: '카카오맵 menuInfo.menuList', diff --git a/src/entities/place-for-map.entity.ts b/src/entities/place-for-map.entity.ts new file mode 100644 index 0000000..13a33be --- /dev/null +++ b/src/entities/place-for-map.entity.ts @@ -0,0 +1,53 @@ +import { + Entity, + EntityRepositoryType, + ManyToOne, + OneToOne, + PrimaryKeyProp, + Property, + Rel, +} from '@mikro-orm/core'; + +import { GroupMap } from './group-map.entity'; +import { PlaceForMapRepository } from './place-for-map.repository'; +import { Place } from './place.entity'; +import { User } from './user.entity'; + +@Entity({ + comment: 'GroupMap에 속한 Place', + repository: () => PlaceForMapRepository, +}) +export class PlaceForMap { + @ManyToOne(() => GroupMap, { primary: true }) + map: Rel; + + @ManyToOne(() => Place, { primary: true }) + place: Rel; + + // 나중에 정규화 하고싶으면 PlaceForMapPhoto라는 Entity를 만들어서 관리하면 될듯. + @Property({ + type: 'json', + comment: '사진 URL과 코멘트를 담은 객체 배열', + }) + comments: { photoUrls: string[]; comment: string; userId: number }[]; + + // 나중에 정규화 하고싶으면 PlaceForMapLike라는 Entity를 만들어서 관리하면 될듯. + @Property({ + type: 'json', + comment: '좋아요 누른 유저 ID 배열', + }) + likedUserIds: number[]; + + @OneToOne(() => User) + createdBy: User; + + @Property() + createdAt: Date = new Date(); + + @Property({ onUpdate: () => new Date() }) + updatedAt: Date = new Date(); + + [PrimaryKeyProp]: ['map', 'place']; + + [EntityRepositoryType]: PlaceForMapRepository; +} diff --git a/src/entities/place-for-map.repository.ts b/src/entities/place-for-map.repository.ts new file mode 100644 index 0000000..51eb1c1 --- /dev/null +++ b/src/entities/place-for-map.repository.ts @@ -0,0 +1,5 @@ +import { ExtendedEntityRepository } from 'src/common/helper/extended-repository.helper'; + +import { PlaceForMap } from './place-for-map.entity'; + +export class PlaceForMapRepository extends ExtendedEntityRepository {} diff --git a/src/entities/place.entity.ts b/src/entities/place.entity.ts new file mode 100644 index 0000000..ab17f98 --- /dev/null +++ b/src/entities/place.entity.ts @@ -0,0 +1,46 @@ +import { + Entity, + EntityRepositoryType, + OneToOne, + PrimaryKey, + Property, +} from '@mikro-orm/core'; + +import { KakaoPlace } from './kakao-place.entity'; +import { PlaceRepository } from './place.repository'; + +@Entity({ + comment: '장소 정보', + repository: () => PlaceRepository, +}) +export class Place { + @PrimaryKey({ + type: 'integer', + autoincrement: true, + }) + id: number; + + // OneToOne + @OneToOne({ entity: () => KakaoPlace }) + kakaoPlace: KakaoPlace; + + @Property({ + type: 'integer', + comment: '경도', + }) + x: number; + + @Property({ + type: 'integer', + comment: '위도', + }) + y: number; + + @Property() + createdAt: Date = new Date(); + + @Property({ onUpdate: () => new Date() }) + updatedAt: Date = new Date(); + + [EntityRepositoryType]: PlaceRepository; +} diff --git a/src/entities/place.repository.ts b/src/entities/place.repository.ts new file mode 100644 index 0000000..94a39fa --- /dev/null +++ b/src/entities/place.repository.ts @@ -0,0 +1,5 @@ +import { ExtendedEntityRepository } from 'src/common/helper/extended-repository.helper'; + +import { Place } from './place.entity'; + +export class PlaceRepository extends ExtendedEntityRepository {} diff --git a/src/migrations/.snapshot-korrk-stage.json b/src/migrations/.snapshot-korrk-stage.json index 7bf5a11..db9083f 100644 --- a/src/migrations/.snapshot-korrk-stage.json +++ b/src/migrations/.snapshot-korrk-stage.json @@ -112,6 +112,28 @@ "comment": "카카오맵 basicInfo.address.newaddr.newaddrfull", "mappedType": "string" }, + "x": { + "name": "x", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "comment": "카카오맵 경도", + "mappedType": "integer" + }, + "y": { + "name": "y", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "comment": "카카오맵 위도", + "mappedType": "integer" + }, "menu_list": { "name": "menu_list", "type": "jsonb", @@ -178,7 +200,114 @@ "schema": "public", "items": ["USER", "ADMIN"] } - } + }, + "comment": "카카오맵에서 제공하는 장소" + }, + { + "columns": { + "id": { + "name": "id", + "type": "serial", + "unsigned": true, + "autoincrement": true, + "primary": true, + "nullable": false, + "mappedType": "integer" + }, + "kakao_place_id": { + "name": "kakao_place_id", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "integer" + }, + "x": { + "name": "x", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "comment": "경도", + "mappedType": "integer" + }, + "y": { + "name": "y", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "comment": "위도", + "mappedType": "integer" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "place", + "schema": "public", + "indexes": [ + { + "columnNames": ["kakao_place_id"], + "composite": false, + "keyName": "place_kakao_place_id_unique", + "constraint": true, + "primary": false, + "unique": true + }, + { + "keyName": "place_pkey", + "columnNames": ["id"], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "place_kakao_place_id_foreign": { + "constraintName": "place_kakao_place_id_foreign", + "columnNames": ["kakao_place_id"], + "localTableName": "public.place", + "referencedColumnNames": ["id"], + "referencedTableName": "public.kakao_place", + "updateRule": "cascade" + } + }, + "nativeEnums": { + "user_provider": { + "name": "user_provider", + "schema": "public", + "items": ["KAKAO"] + }, + "user_role": { + "name": "user_role", + "schema": "public", + "items": ["USER", "ADMIN"] + } + }, + "comment": "장소 정보" }, { "columns": { @@ -315,6 +444,137 @@ } } }, + { + "columns": { + "map_id": { + "name": "map_id", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "string" + }, + "place_id": { + "name": "place_id", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "integer" + }, + "comments": { + "name": "comments", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "comment": "사진 URL과 코멘트를 담은 객체 배열", + "mappedType": "json" + }, + "liked_user_ids": { + "name": "liked_user_ids", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "comment": "좋아요 누른 유저 ID 배열", + "mappedType": "json" + }, + "created_by_id": { + "name": "created_by_id", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "integer" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "place_for_map", + "schema": "public", + "indexes": [ + { + "columnNames": ["created_by_id"], + "composite": false, + "keyName": "place_for_map_created_by_id_unique", + "constraint": true, + "primary": false, + "unique": true + }, + { + "keyName": "place_for_map_pkey", + "columnNames": ["map_id", "place_id"], + "composite": true, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "place_for_map_map_id_foreign": { + "constraintName": "place_for_map_map_id_foreign", + "columnNames": ["map_id"], + "localTableName": "public.place_for_map", + "referencedColumnNames": ["id"], + "referencedTableName": "public.map", + "updateRule": "cascade" + }, + "place_for_map_place_id_foreign": { + "constraintName": "place_for_map_place_id_foreign", + "columnNames": ["place_id"], + "localTableName": "public.place_for_map", + "referencedColumnNames": ["id"], + "referencedTableName": "public.place", + "updateRule": "cascade" + }, + "place_for_map_created_by_id_foreign": { + "constraintName": "place_for_map_created_by_id_foreign", + "columnNames": ["created_by_id"], + "localTableName": "public.place_for_map", + "referencedColumnNames": ["id"], + "referencedTableName": "public.user", + "updateRule": "cascade" + } + }, + "nativeEnums": { + "user_provider": { + "name": "user_provider", + "schema": "public", + "items": ["KAKAO"] + }, + "user_role": { + "name": "user_role", + "schema": "public", + "items": ["USER", "ADMIN"] + } + }, + "comment": "GroupMap에 속한 Place" + }, { "columns": { "user_id": { diff --git a/src/migrations/Migration20240629185552.ts b/src/migrations/Migration20240629185552.ts new file mode 100644 index 0000000..f9d77fa --- /dev/null +++ b/src/migrations/Migration20240629185552.ts @@ -0,0 +1,68 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20240629185552 extends Migration { + async up(): Promise { + this.addSql( + 'create table "place" ("id" serial primary key, "kakao_place_id" int not null, "x" int not null, "y" int not null, "created_at" timestamptz not null, "updated_at" timestamptz not null);', + ); + this.addSql('comment on table "place" is \'장소 정보\';'); + this.addSql('comment on column "place"."x" is \'경도\';'); + this.addSql('comment on column "place"."y" is \'위도\';'); + this.addSql( + 'alter table "place" add constraint "place_kakao_place_id_unique" unique ("kakao_place_id");', + ); + + this.addSql( + 'create table "place_for_map" ("map_id" varchar(255) not null, "place_id" int not null, "comments" jsonb not null, "liked_user_ids" jsonb not null, "created_by_id" int not null, "created_at" timestamptz not null, "updated_at" timestamptz not null, constraint "place_for_map_pkey" primary key ("map_id", "place_id"));', + ); + this.addSql( + 'comment on table "place_for_map" is \'GroupMap에 속한 Place\';', + ); + this.addSql( + 'comment on column "place_for_map"."comments" is \'사진 URL과 코멘트를 담은 객체 배열\';', + ); + this.addSql( + 'comment on column "place_for_map"."liked_user_ids" is \'좋아요 누른 유저 ID 배열\';', + ); + this.addSql( + 'alter table "place_for_map" add constraint "place_for_map_created_by_id_unique" unique ("created_by_id");', + ); + + this.addSql( + 'alter table "place" add constraint "place_kakao_place_id_foreign" foreign key ("kakao_place_id") references "kakao_place" ("id") on update cascade;', + ); + + this.addSql( + 'alter table "place_for_map" add constraint "place_for_map_map_id_foreign" foreign key ("map_id") references "map" ("id") on update cascade;', + ); + this.addSql( + 'alter table "place_for_map" add constraint "place_for_map_place_id_foreign" foreign key ("place_id") references "place" ("id") on update cascade;', + ); + this.addSql( + 'alter table "place_for_map" add constraint "place_for_map_created_by_id_foreign" foreign key ("created_by_id") references "user" ("id") on update cascade;', + ); + + this.addSql( + 'alter table "kakao_place" add column "x" int not null default 0, add column "y" int not null default 0;', + ); + this.addSql('comment on column "kakao_place"."x" is \'카카오맵 경도\';'); + this.addSql('comment on column "kakao_place"."y" is \'카카오맵 위도\';'); + this.addSql( + 'comment on table "kakao_place" is \'카카오맵에서 제공하는 장소\';', + ); + } + + async down(): Promise { + this.addSql( + 'alter table "place_for_map" drop constraint "place_for_map_place_id_foreign";', + ); + + this.addSql('drop table if exists "place" cascade;'); + + this.addSql('drop table if exists "place_for_map" cascade;'); + + this.addSql('alter table "kakao_place" drop column "x", drop column "y";'); + + this.addSql('comment on table "kakao_place" is \'\';'); + } +} diff --git a/src/place/place.controller.ts b/src/place/place.controller.ts new file mode 100644 index 0000000..8dc149e --- /dev/null +++ b/src/place/place.controller.ts @@ -0,0 +1,90 @@ +import { Controller, Delete, Get, Param, Put } from '@nestjs/common'; +import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; + +import { UseAuthGuard } from '../common/decorators/auth-guard.decorator'; +import { CurrentUser } from '../common/decorators/user.decorator'; +import { User, UserRole } from '../entities'; +import { PlaceService } from './place.service'; + +@ApiTags('place') +@Controller('place') +export class PlaceController { + constructor(private readonly placeService: PlaceService) {} + + @ApiOperation({ summary: '맛집지도 (GroupMap)에 등록된 장소 전부 가져오기' }) + @ApiParam({ name: 'mapId', description: '지도(GroupMap) id' }) + @Get(':mapId') + async getAllPlaceForMap(@Param('mapId') mapId: string) { + return await this.placeService.getAllPlacesForMap({ + mapId, + }); + } + + @ApiOperation({ summary: '카카오 place id로 장소 등록' }) + @ApiParam({ name: 'mapId', description: '지도(GroupMap) id' }) + @ApiParam({ name: 'kakaoPlaceId', description: '카카오 place id' }) + @UseAuthGuard([UserRole.USER]) + @Put(':mapId/kakao/:kakaoPlaceId') + async registerPlaceByKakaoId( + @Param('mapId') mapId: string, + @Param('kakaoPlaceId') kakaoPlaceId: number, + @CurrentUser() user: User, + ) { + return await this.placeService.registerPlaceByKakaoId({ + mapId, + kakaoPlaceId, + user, + }); + } + + @ApiOperation({ summary: '맛집 장소 삭제' }) + @ApiParam({ name: 'mapId', description: '지도(GroupMap) id' }) + @ApiParam({ name: 'placeId', description: 'place id' }) + @UseAuthGuard([UserRole.USER]) + @Delete(':mapId/:placeId') + async deletePlaceByKakaoId( + @Param('mapId') mapId: string, + @Param('placeId') placeId: number, + @CurrentUser() user: User, + ) { + // TODO: + throw new Error('Not implemented'); + } + + @ApiOperation({ summary: '맛집 좋아요' }) + @ApiParam({ name: 'mapId', description: '지도(GroupMap) id' }) + @ApiParam({ name: 'placeId', description: 'place id' }) + @UseAuthGuard([UserRole.USER]) + @Put(':mapId/:placeId/like') + async likePlace( + @Param('mapId') mapId: string, + @Param('placeId') placeId: number, + @CurrentUser() user: User, + ) { + return await this.placeService.likePlace({ + mapId, + placeId, + user, + like: true, + }); + } + + @ApiOperation({ summary: '맛집 좋아요 취소' }) + @ApiParam({ name: 'mapId', description: '지도(GroupMap) id' }) + @ApiParam({ name: 'placeId', description: 'place id' }) + @UseAuthGuard([UserRole.USER]) + @Delete(':mapId/:placeId/like') + async dislikePlace( + @Param('mapId') mapId: string, + @Param('placeId') placeId: number, + @CurrentUser() user: User, + ) { + // TODO: + return await this.placeService.likePlace({ + mapId, + placeId, + user, + like: false, + }); + } +} diff --git a/src/place/place.module.ts b/src/place/place.module.ts new file mode 100644 index 0000000..ac8fefd --- /dev/null +++ b/src/place/place.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; + +import { MikroOrmModule } from '@mikro-orm/nestjs'; + +import { GroupMap, KakaoPlace, Place, PlaceForMap } from '../entities'; +import { SearchModule } from '../search/search.module'; +import { PlaceController } from './place.controller'; +import { PlaceService } from './place.service'; + +@Module({ + imports: [ + SearchModule, + MikroOrmModule.forFeature([Place, KakaoPlace, PlaceForMap, GroupMap]), + ], + controllers: [PlaceController], + providers: [PlaceService], +}) +export class PlaceModule {} diff --git a/src/place/place.service.ts b/src/place/place.service.ts new file mode 100644 index 0000000..520f50a --- /dev/null +++ b/src/place/place.service.ts @@ -0,0 +1,118 @@ +import { Injectable } from '@nestjs/common'; + +import { rel } from '@mikro-orm/core'; +import { InjectRepository } from '@mikro-orm/nestjs'; + +import { + GroupMap, + KakaoPlace, + Place, + PlaceForMap, + PlaceForMapRepository, + PlaceRepository, + User, +} from '../entities'; +import { SearchService } from '../search/search.service'; + +@Injectable() +export class PlaceService { + constructor( + @InjectRepository(Place) + private readonly placeRepository: PlaceRepository, + @InjectRepository(PlaceForMap) + private readonly placeForMapRepository: PlaceForMapRepository, + private readonly searchService: SearchService, + ) {} + + /** + * map id (GroupMap.id)에 속한 장소를 전부 가져옵니다. + * TODO: 나중에 커지면 geo-query + pagination 해야할듯 + */ + async getAllPlacesForMap({ mapId }: { mapId: string }) { + const placesForMapList = await this.placeForMapRepository.find( + { + map: rel(GroupMap, mapId), + }, + { populate: ['place', 'place.kakaoPlace', 'createdBy'] }, + ); + + return placesForMapList; + } + + async registerPlaceByKakaoId({ + kakaoPlaceId, + mapId, + user, + }: { + kakaoPlaceId: number; + mapId: string; + user: User; + }) { + // create place if not exist + let place = await this.placeRepository.findOne({ + kakaoPlace: rel(KakaoPlace, kakaoPlaceId), + }); + if (place == null) { + const kakaoPlace = await this.searchService.searchPlaceDetail( + kakaoPlaceId.toString(), + false, + ); + place = new Place(); + place.kakaoPlace = kakaoPlace; + place.x = kakaoPlace.x; + place.y = kakaoPlace.y; + } + await this.placeRepository.persistAndFlush(place); + + // create place for map if not exist + let placeForMap = await this.placeForMapRepository.findOne({ + place, + map: rel(GroupMap, mapId), + }); + + if (placeForMap == null) { + placeForMap = new PlaceForMap(); + placeForMap.place = place; + placeForMap.map = rel(GroupMap, mapId); + placeForMap.createdBy = user; + placeForMap.comments = []; + placeForMap.likedUserIds = []; + } + await this.placeForMapRepository.persistAndFlush(placeForMap); + + return placeForMap; + } + + async likePlace({ + mapId, + placeId, + user, + like, + }: { + mapId: string; + placeId: number; + user: User; + like: boolean; + }) { + const placeForMap = await this.placeForMapRepository.findOneOrFail( + { + place: rel(Place, placeId), + map: rel(GroupMap, mapId), + }, + { populate: ['place', 'place.kakaoPlace', 'createdBy'] }, + ); + + if (like && !placeForMap.likedUserIds.includes(user.id)) { + placeForMap.likedUserIds = [...placeForMap.likedUserIds, user.id]; + } + + if (!like && placeForMap.likedUserIds.includes(user.id)) { + placeForMap.likedUserIds = placeForMap.likedUserIds.filter( + (id) => id !== user.id, + ); + } + + await this.placeForMapRepository.persistAndFlush(placeForMap); + return placeForMap; + } +} diff --git a/src/search/search.module.ts b/src/search/search.module.ts index 1ecbcfc..a33776d 100644 --- a/src/search/search.module.ts +++ b/src/search/search.module.ts @@ -12,5 +12,6 @@ import { SearchService } from './search.service'; imports: [HttpModule, MikroOrmModule.forFeature([KakaoPlace])], controllers: [SearchController], providers: [SearchService, KakaoMapHelper], + exports: [SearchService], }) export class SearchModule {} diff --git a/src/search/search.service.ts b/src/search/search.service.ts index fe3e6f2..88f9009 100644 --- a/src/search/search.service.ts +++ b/src/search/search.service.ts @@ -72,6 +72,14 @@ export class SearchService { ({ menu, price }) => ({ menu, price }), ); + // set coordinate + const coord = await this.kakaoMapHelper.congnamulToLongLat( + kakaoPlaceRaw.basicInfo.wpointx, + kakaoPlaceRaw.basicInfo.wpointy, + ); + kakaoPlace.x = coord.x; + kakaoPlace.y = coord.y; + // TODO: 음식사진 가져오는것도 약간 우선순위를 두면 좋을듯 kakaoPlace.photoList = kakaoPlaceRaw.photo.photoList .flatMap((photo) => photo.list)