From d6e9adb3877f21fda70d068df980eb70d4d2e424 Mon Sep 17 00:00:00 2001 From: ceunjinn Date: Thu, 5 Dec 2024 22:58:27 +0900 Subject: [PATCH 1/2] test1 --- .gradle/8.0/checksums/checksums.lock | Bin 17 -> 0 bytes .gradle/8.0/checksums/md5-checksums.bin | Bin 33397 -> 0 bytes .gradle/8.0/checksums/sha1-checksums.bin | Bin 110558 -> 0 bytes .../dependencies-accessors.lock | Bin 17 -> 0 bytes .../8.0/dependencies-accessors/gc.properties | 0 .../8.0/executionHistory/executionHistory.bin | Bin 44088 -> 0 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 0 bytes .gradle/8.0/fileChanges/last-build.bin | Bin 1 -> 0 bytes .gradle/8.0/fileHashes/fileHashes.bin | Bin 20097 -> 0 bytes .gradle/8.0/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .../8.0/fileHashes/resourceHashesCache.bin | Bin 19109 -> 0 bytes .gradle/8.0/gc.properties | 0 .gradle/8.10.2/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../umc/spring/domain/QFoodCategory.java | 50 ++++++++++++++ .../generated/umc/spring/domain/QMember.java | 18 +++-- .../generated/umc/spring/domain/QMission.java | 22 +++--- .../generated/umc/spring/domain/QRegion.java | 10 +-- .../generated/umc/spring/domain/QReview.java | 11 ++- .../domain/{QRestaurant.java => QStore.java} | 28 ++++---- .../generated/umc/spring/domain/QTerms.java | 54 +++++++++++++++ .../spring/domain/mapping/QMemberAgree.java | 62 +++++++++++++++++ .../spring/domain/mapping/QMemberMission.java | 64 ++++++++++++++++++ .../spring/domain/mapping/QMemberPrefer.java | 62 +++++++++++++++++ src/main/java/umc/spring/Application.java | 10 +-- .../apiPayload/code/status/ErrorStatus.java | 3 +- .../ExceptionAdvice.java | 4 +- .../GeneralException.java | 13 ++-- .../handler/TempHandler.java | 4 +- .../java/umc/spring/domain/FoodCategory.java | 29 ++++++++ src/main/java/umc/spring/domain/Member.java | 44 ++++++++---- src/main/java/umc/spring/domain/Mission.java | 33 ++++----- src/main/java/umc/spring/domain/Region.java | 12 +--- src/main/java/umc/spring/domain/Review.java | 18 +++-- .../domain/{Restaurant.java => Store.java} | 24 +++---- src/main/java/umc/spring/domain/Terms.java | 32 +++++++++ .../enums/{Status.java => MemberStatus.java} | 3 +- .../spring/domain/enums/MissionStatus.java | 6 ++ .../umc/spring/domain/enums/SocialType.java | 6 ++ .../spring/domain/mapping/MemberAgree.java | 27 ++++++++ .../spring/domain/mapping/MemberMission.java | 33 +++++++++ .../spring/domain/mapping/MemberPrefer.java | 27 ++++++++ .../RestaurantRepository.java | 9 --- .../RestaurantRepositoryCustom.java | 8 --- .../StoreRepository/StoreRepository.java | 7 ++ .../StoreRepositoryCustom.java | 9 +++ .../StoreRepositoryImpl.java} | 19 +++--- .../RestaurantQueryService.java | 12 ---- .../RestaurantQueryServiceImpl.java | 34 ---------- .../StoreService/StoreQueryService.java | 12 ++++ .../StoreService/StoreQueryServiceImpl.java | 32 +++++++++ ...iceImpl.java => TempCommandQueryImpl.java} | 4 +- .../service/TempService/TempQueryService.java | 1 + .../web/controller/TempRestController.java | 2 +- .../java/umc/spring/web/dto/TempRequest.java | 6 -- src/main/resources/Application.yml | 2 +- src/main/resources/application.yml | 2 +- 56 files changed, 652 insertions(+), 216 deletions(-) delete mode 100644 .gradle/8.0/checksums/checksums.lock delete mode 100644 .gradle/8.0/checksums/md5-checksums.bin delete mode 100644 .gradle/8.0/checksums/sha1-checksums.bin delete mode 100644 .gradle/8.0/dependencies-accessors/dependencies-accessors.lock delete mode 100644 .gradle/8.0/dependencies-accessors/gc.properties delete mode 100644 .gradle/8.0/executionHistory/executionHistory.bin delete mode 100644 .gradle/8.0/executionHistory/executionHistory.lock delete mode 100644 .gradle/8.0/fileChanges/last-build.bin delete mode 100644 .gradle/8.0/fileHashes/fileHashes.bin delete mode 100644 .gradle/8.0/fileHashes/fileHashes.lock delete mode 100644 .gradle/8.0/fileHashes/resourceHashesCache.bin delete mode 100644 .gradle/8.0/gc.properties create mode 100644 src/main/generated/umc/spring/domain/QFoodCategory.java rename src/main/generated/umc/spring/domain/{QRestaurant.java => QStore.java} (56%) create mode 100644 src/main/generated/umc/spring/domain/QTerms.java create mode 100644 src/main/generated/umc/spring/domain/mapping/QMemberAgree.java create mode 100644 src/main/generated/umc/spring/domain/mapping/QMemberMission.java create mode 100644 src/main/generated/umc/spring/domain/mapping/QMemberPrefer.java rename src/main/java/umc/spring/apiPayload/{Exception => exception}/ExceptionAdvice.java (99%) rename src/main/java/umc/spring/apiPayload/{Exception => exception}/GeneralException.java (58%) rename src/main/java/umc/spring/apiPayload/{Exception => exception}/handler/TempHandler.java (63%) create mode 100644 src/main/java/umc/spring/domain/FoodCategory.java rename src/main/java/umc/spring/domain/{Restaurant.java => Store.java} (64%) create mode 100644 src/main/java/umc/spring/domain/Terms.java rename src/main/java/umc/spring/domain/enums/{Status.java => MemberStatus.java} (67%) create mode 100644 src/main/java/umc/spring/domain/enums/MissionStatus.java create mode 100644 src/main/java/umc/spring/domain/enums/SocialType.java create mode 100644 src/main/java/umc/spring/domain/mapping/MemberAgree.java create mode 100644 src/main/java/umc/spring/domain/mapping/MemberMission.java create mode 100644 src/main/java/umc/spring/domain/mapping/MemberPrefer.java delete mode 100644 src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepository.java delete mode 100644 src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryCustom.java create mode 100644 src/main/java/umc/spring/repository/StoreRepository/StoreRepository.java create mode 100644 src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryCustom.java rename src/main/java/umc/spring/repository/{RestaurantRepository/RestaurantRepositoryImpl.java => StoreRepository/StoreRepositoryImpl.java} (51%) delete mode 100644 src/main/java/umc/spring/service/RestaurantService/RestaurantQueryService.java delete mode 100644 src/main/java/umc/spring/service/RestaurantService/RestaurantQueryServiceImpl.java create mode 100644 src/main/java/umc/spring/service/StoreService/StoreQueryService.java create mode 100644 src/main/java/umc/spring/service/StoreService/StoreQueryServiceImpl.java rename src/main/java/umc/spring/service/TempService/{TempQueryServiceImpl.java => TempCommandQueryImpl.java} (74%) delete mode 100644 src/main/java/umc/spring/web/dto/TempRequest.java diff --git a/.gradle/8.0/checksums/checksums.lock b/.gradle/8.0/checksums/checksums.lock deleted file mode 100644 index c5d70e543cc06dc21a94843bf71b81ee53b9717d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZS1%hw3dZ(bP200yis03}!hO8@`> diff --git a/.gradle/8.0/checksums/md5-checksums.bin b/.gradle/8.0/checksums/md5-checksums.bin deleted file mode 100644 index 11062ace9942423f2a52bf25e02e9676ec387fd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33397 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 z 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 CIvJV( diff --git a/.gradle/8.0/fileHashes/fileHashes.lock b/.gradle/8.0/fileHashes/fileHashes.lock deleted file mode 100644 index 9256141324f9dc3e721c56162390cc7a6d13a601..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZSnx|lE3RMh_%0|d+k04)*(3jhEB diff --git a/.gradle/8.0/fileHashes/resourceHashesCache.bin b/.gradle/8.0/fileHashes/resourceHashesCache.bin deleted file mode 100644 index d06b27c3835bdfb2edb23789fbadc7ee9c95c59e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19109 zcmeI(`Ad^=0LSrZy3*1#@d}RynPrw|*7B|eUWIO6l^q^*QKoGoqJ}!HB(t9+YL8Im*x!R*4yu=9M+Flu5_No-a~Qe?ff)+aBKg?Ae~zuVWkr!_43(bz>~t zj28}Z1OW&@00Izz00bZa0SG_<0uX=z1Rwwb2tWV=5P-nHA`qs$5MA}fnAvNp4wfe~ z7>>)72P<;L;~!a`9zylYeq!?b!Fgv^r12Mahq?zulb%;4uT$(Up}Joz=@ojJM`~xM z1J!%~5Yl^XV{TZ_JYG!oBGLy;EVyPRot@O@PLeL$SZG)5G%`%>Uy(kExNg&}dh`2agbd00bZa0SG_<0uX=z1Rwwb2tWV= z5P$##AOHafKmY;|fB*y_009U<00Izz00bZa0SG_<0uX=z1R(Ig3AiXP*j#xxRNW1< zl0*k8r_PDjor=zFTy)n)8LfU_M7Zu0aI4#|Rm25PdHHcv{~`Eek=8g-5n9JSHnTp$ zT4>~COJ4*f@WWU}K0Nz-OWww~gzTd)w4QwW@zva<-%UrpEz>1?n!YG(5hs3Iqcdt? zDT^1B*|yRb-EZ20OEVpY*^-{=uIF1T|FWn_Z5F0J-s2K|kv0=I=d&SS-)MkWXeP^;r!V+6k#;RS?d}JTIsVMV+${Q{!81Snis*gN z;1;oa!xvV zt}2y>YD#O}Yv_xm`r}Cfk1|rr+iuB=*7BR^3ntqtoXH&1-eEMyGm(pY=nJ0vroAtP SPdU*NPLytMg6h8vR=)t5ZjaUg diff --git a/.gradle/8.0/gc.properties b/.gradle/8.0/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/8.10.2/fileHashes/fileHashes.lock b/.gradle/8.10.2/fileHashes/fileHashes.lock index 5b51efe08c174052928979dec54980e07160ba0b..22cf583651f986cf75ff89566ced5fc115a44dfb 100644 GIT binary patch literal 17 TcmZQ({c)6s*SC_90RlPzBeVl9 literal 17 TcmZQ({c)6s*SC_90Rq|pBeDZ5 diff --git a/src/main/generated/umc/spring/domain/QFoodCategory.java b/src/main/generated/umc/spring/domain/QFoodCategory.java new file mode 100644 index 0000000..1667676 --- /dev/null +++ b/src/main/generated/umc/spring/domain/QFoodCategory.java @@ -0,0 +1,50 @@ +package umc.spring.domain; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QFoodCategory is a Querydsl query type for FoodCategory + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QFoodCategory extends EntityPathBase { + + private static final long serialVersionUID = -811463128L; + + public static final QFoodCategory foodCategory = new QFoodCategory("foodCategory"); + + public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); + + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final NumberPath id = createNumber("id", Long.class); + + public final ListPath memberPreferList = this.createList("memberPreferList", umc.spring.domain.mapping.MemberPrefer.class, umc.spring.domain.mapping.QMemberPrefer.class, PathInits.DIRECT2); + + public final StringPath name = createString("name"); + + //inherited + public final DateTimePath updatedAt = _super.updatedAt; + + public QFoodCategory(String variable) { + super(FoodCategory.class, forVariable(variable)); + } + + public QFoodCategory(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QFoodCategory(PathMetadata metadata) { + super(FoodCategory.class, metadata); + } + +} + diff --git a/src/main/generated/umc/spring/domain/QMember.java b/src/main/generated/umc/spring/domain/QMember.java index c4ab5f2..fcd434a 100644 --- a/src/main/generated/umc/spring/domain/QMember.java +++ b/src/main/generated/umc/spring/domain/QMember.java @@ -24,12 +24,10 @@ public class QMember extends EntityPathBase { public final StringPath address = createString("address"); - public final DatePath birth = createDate("birth", java.time.LocalDate.class); - //inherited public final DateTimePath createdAt = _super.createdAt; - public final StringPath favoriteFood = createString("favoriteFood"); + public final StringPath email = createString("email"); public final EnumPath gender = createEnum("gender", umc.spring.domain.enums.Gender.class); @@ -37,15 +35,23 @@ public class QMember extends EntityPathBase { public final DatePath inactiveDate = createDate("inactiveDate", java.time.LocalDate.class); - public final ListPath MissionList = this.createList("MissionList", Mission.class, QMission.class, PathInits.DIRECT2); + public final ListPath memberAgreeList = this.createList("memberAgreeList", umc.spring.domain.mapping.MemberAgree.class, umc.spring.domain.mapping.QMemberAgree.class, PathInits.DIRECT2); + + public final ListPath memberMissionList = this.createList("memberMissionList", umc.spring.domain.mapping.MemberMission.class, umc.spring.domain.mapping.QMemberMission.class, PathInits.DIRECT2); + + public final ListPath memberPreferList = this.createList("memberPreferList", umc.spring.domain.mapping.MemberPrefer.class, umc.spring.domain.mapping.QMemberPrefer.class, PathInits.DIRECT2); public final StringPath name = createString("name"); public final NumberPath point = createNumber("point", Integer.class); - public final ListPath ReviewList = this.createList("ReviewList", Review.class, QReview.class, PathInits.DIRECT2); + public final ListPath reviewList = this.createList("reviewList", Review.class, QReview.class, PathInits.DIRECT2); + + public final EnumPath SocialType = createEnum("SocialType", umc.spring.domain.enums.SocialType.class); + + public final StringPath specAddress = createString("specAddress"); - public final EnumPath status = createEnum("status", umc.spring.domain.enums.Status.class); + public final EnumPath status = createEnum("status", umc.spring.domain.enums.MemberStatus.class); //inherited public final DateTimePath updatedAt = _super.updatedAt; diff --git a/src/main/generated/umc/spring/domain/QMission.java b/src/main/generated/umc/spring/domain/QMission.java index adde652..ffdb84f 100644 --- a/src/main/generated/umc/spring/domain/QMission.java +++ b/src/main/generated/umc/spring/domain/QMission.java @@ -22,21 +22,25 @@ public class QMission extends EntityPathBase { public static final QMission mission = new QMission("mission"); - public final NumberPath code = createNumber("code", Integer.class); + public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); - public final StringPath content = createString("content"); + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final DatePath deadline = createDate("deadline", java.time.LocalDate.class); public final NumberPath id = createNumber("id", Long.class); - public final BooleanPath isSuccess = createBoolean("isSuccess"); + public final ListPath memberMissionList = this.createList("memberMissionList", umc.spring.domain.mapping.MemberMission.class, umc.spring.domain.mapping.QMemberMission.class, PathInits.DIRECT2); - public final QMember member; + public final StringPath missionSpec = createString("missionSpec"); - public final QRegion region; + public final NumberPath reward = createNumber("reward", Integer.class); - public final QRestaurant restaurant; + public final QStore store; - public final EnumPath status = createEnum("status", umc.spring.domain.enums.Status.class); + //inherited + public final DateTimePath updatedAt = _super.updatedAt; public QMission(String variable) { this(Mission.class, forVariable(variable), INITS); @@ -56,9 +60,7 @@ public QMission(PathMetadata metadata, PathInits inits) { public QMission(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); - this.member = inits.isInitialized("member") ? new QMember(forProperty("member")) : null; - this.region = inits.isInitialized("region") ? new QRegion(forProperty("region")) : null; - this.restaurant = inits.isInitialized("restaurant") ? new QRestaurant(forProperty("restaurant"), inits.get("restaurant")) : null; + this.store = inits.isInitialized("store") ? new QStore(forProperty("store"), inits.get("store")) : null; } } diff --git a/src/main/generated/umc/spring/domain/QRegion.java b/src/main/generated/umc/spring/domain/QRegion.java index a65d4bb..1ca2dee 100644 --- a/src/main/generated/umc/spring/domain/QRegion.java +++ b/src/main/generated/umc/spring/domain/QRegion.java @@ -27,17 +27,9 @@ public class QRegion extends EntityPathBase { public final NumberPath id = createNumber("id", Long.class); - public final BooleanPath isRewarded = createBoolean("isRewarded"); - - public final ListPath MissionList = this.createList("MissionList", Mission.class, QMission.class, PathInits.DIRECT2); - public final StringPath name = createString("name"); - public final ListPath RestaurantList = this.createList("RestaurantList", Restaurant.class, QRestaurant.class, PathInits.DIRECT2); - - public final ListPath ReviewList = this.createList("ReviewList", Review.class, QReview.class, PathInits.DIRECT2); - - public final NumberPath successNumber = createNumber("successNumber", Integer.class); + public final ListPath storeList = this.createList("storeList", Store.class, QStore.class, PathInits.DIRECT2); //inherited public final DateTimePath updatedAt = _super.updatedAt; diff --git a/src/main/generated/umc/spring/domain/QReview.java b/src/main/generated/umc/spring/domain/QReview.java index 4bfc041..80c4c65 100644 --- a/src/main/generated/umc/spring/domain/QReview.java +++ b/src/main/generated/umc/spring/domain/QReview.java @@ -24,8 +24,6 @@ public class QReview extends EntityPathBase { public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); - public final StringPath content = createString("content"); - //inherited public final DateTimePath createdAt = _super.createdAt; @@ -33,11 +31,11 @@ public class QReview extends EntityPathBase { public final QMember member; - public final QRegion region; + public final NumberPath score = createNumber("score", Float.class); - public final QRestaurant restaurant; + public final QStore store; - public final NumberPath score = createNumber("score", Integer.class); + public final StringPath title = createString("title"); //inherited public final DateTimePath updatedAt = _super.updatedAt; @@ -61,8 +59,7 @@ public QReview(PathMetadata metadata, PathInits inits) { public QReview(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); this.member = inits.isInitialized("member") ? new QMember(forProperty("member")) : null; - this.region = inits.isInitialized("region") ? new QRegion(forProperty("region")) : null; - this.restaurant = inits.isInitialized("restaurant") ? new QRestaurant(forProperty("restaurant"), inits.get("restaurant")) : null; + this.store = inits.isInitialized("store") ? new QStore(forProperty("store"), inits.get("store")) : null; } } diff --git a/src/main/generated/umc/spring/domain/QRestaurant.java b/src/main/generated/umc/spring/domain/QStore.java similarity index 56% rename from src/main/generated/umc/spring/domain/QRestaurant.java rename to src/main/generated/umc/spring/domain/QStore.java index def0ec7..b983e06 100644 --- a/src/main/generated/umc/spring/domain/QRestaurant.java +++ b/src/main/generated/umc/spring/domain/QStore.java @@ -11,16 +11,16 @@ /** - * QRestaurant is a Querydsl query type for Restaurant + * QStore is a Querydsl query type for Store */ @Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QRestaurant extends EntityPathBase { +public class QStore extends EntityPathBase { - private static final long serialVersionUID = 1563043049L; + private static final long serialVersionUID = 1158464437L; private static final PathInits INITS = PathInits.DIRECT2; - public static final QRestaurant restaurant = new QRestaurant("restaurant"); + public static final QStore store = new QStore("store"); public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); @@ -31,36 +31,34 @@ public class QRestaurant extends EntityPathBase { public final NumberPath id = createNumber("id", Long.class); - public final ListPath Mission = this.createList("Mission", Mission.class, QMission.class, PathInits.DIRECT2); - public final StringPath name = createString("name"); public final QRegion region; - public final ListPath ReviewList = this.createList("ReviewList", Review.class, QReview.class, PathInits.DIRECT2); + public final ListPath reviewList = this.createList("reviewList", Review.class, QReview.class, PathInits.DIRECT2); - public final NumberPath score = createNumber("score", Integer.class); + public final NumberPath score = createNumber("score", Float.class); //inherited public final DateTimePath updatedAt = _super.updatedAt; - public QRestaurant(String variable) { - this(Restaurant.class, forVariable(variable), INITS); + public QStore(String variable) { + this(Store.class, forVariable(variable), INITS); } - public QRestaurant(Path path) { + public QStore(Path path) { this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); } - public QRestaurant(PathMetadata metadata) { + public QStore(PathMetadata metadata) { this(metadata, PathInits.getFor(metadata, INITS)); } - public QRestaurant(PathMetadata metadata, PathInits inits) { - this(Restaurant.class, metadata, inits); + public QStore(PathMetadata metadata, PathInits inits) { + this(Store.class, metadata, inits); } - public QRestaurant(Class type, PathMetadata metadata, PathInits inits) { + public QStore(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); this.region = inits.isInitialized("region") ? new QRegion(forProperty("region")) : null; } diff --git a/src/main/generated/umc/spring/domain/QTerms.java b/src/main/generated/umc/spring/domain/QTerms.java new file mode 100644 index 0000000..ab70584 --- /dev/null +++ b/src/main/generated/umc/spring/domain/QTerms.java @@ -0,0 +1,54 @@ +package umc.spring.domain; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QTerms is a Querydsl query type for Terms + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QTerms extends EntityPathBase { + + private static final long serialVersionUID = 1158943835L; + + public static final QTerms terms = new QTerms("terms"); + + public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); + + public final StringPath body = createString("body"); + + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final NumberPath id = createNumber("id", Long.class); + + public final ListPath memberAgreeList = this.createList("memberAgreeList", umc.spring.domain.mapping.MemberAgree.class, umc.spring.domain.mapping.QMemberAgree.class, PathInits.DIRECT2); + + public final BooleanPath optional = createBoolean("optional"); + + public final StringPath title = createString("title"); + + //inherited + public final DateTimePath updatedAt = _super.updatedAt; + + public QTerms(String variable) { + super(Terms.class, forVariable(variable)); + } + + public QTerms(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QTerms(PathMetadata metadata) { + super(Terms.class, metadata); + } + +} + diff --git a/src/main/generated/umc/spring/domain/mapping/QMemberAgree.java b/src/main/generated/umc/spring/domain/mapping/QMemberAgree.java new file mode 100644 index 0000000..15b7557 --- /dev/null +++ b/src/main/generated/umc/spring/domain/mapping/QMemberAgree.java @@ -0,0 +1,62 @@ +package umc.spring.domain.mapping; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QMemberAgree is a Querydsl query type for MemberAgree + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QMemberAgree extends EntityPathBase { + + private static final long serialVersionUID = -2051556634L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QMemberAgree memberAgree = new QMemberAgree("memberAgree"); + + public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); + + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final NumberPath id = createNumber("id", Long.class); + + public final umc.spring.domain.QMember member; + + public final umc.spring.domain.QTerms terms; + + //inherited + public final DateTimePath updatedAt = _super.updatedAt; + + public QMemberAgree(String variable) { + this(MemberAgree.class, forVariable(variable), INITS); + } + + public QMemberAgree(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QMemberAgree(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QMemberAgree(PathMetadata metadata, PathInits inits) { + this(MemberAgree.class, metadata, inits); + } + + public QMemberAgree(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.member = inits.isInitialized("member") ? new umc.spring.domain.QMember(forProperty("member")) : null; + this.terms = inits.isInitialized("terms") ? new umc.spring.domain.QTerms(forProperty("terms")) : null; + } + +} + diff --git a/src/main/generated/umc/spring/domain/mapping/QMemberMission.java b/src/main/generated/umc/spring/domain/mapping/QMemberMission.java new file mode 100644 index 0000000..29da571 --- /dev/null +++ b/src/main/generated/umc/spring/domain/mapping/QMemberMission.java @@ -0,0 +1,64 @@ +package umc.spring.domain.mapping; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QMemberMission is a Querydsl query type for MemberMission + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QMemberMission extends EntityPathBase { + + private static final long serialVersionUID = 1962779462L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QMemberMission memberMission = new QMemberMission("memberMission"); + + public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); + + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final NumberPath id = createNumber("id", Long.class); + + public final umc.spring.domain.QMember member; + + public final umc.spring.domain.QMission mission; + + public final EnumPath status = createEnum("status", umc.spring.domain.enums.MissionStatus.class); + + //inherited + public final DateTimePath updatedAt = _super.updatedAt; + + public QMemberMission(String variable) { + this(MemberMission.class, forVariable(variable), INITS); + } + + public QMemberMission(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QMemberMission(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QMemberMission(PathMetadata metadata, PathInits inits) { + this(MemberMission.class, metadata, inits); + } + + public QMemberMission(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.member = inits.isInitialized("member") ? new umc.spring.domain.QMember(forProperty("member")) : null; + this.mission = inits.isInitialized("mission") ? new umc.spring.domain.QMission(forProperty("mission"), inits.get("mission")) : null; + } + +} + diff --git a/src/main/generated/umc/spring/domain/mapping/QMemberPrefer.java b/src/main/generated/umc/spring/domain/mapping/QMemberPrefer.java new file mode 100644 index 0000000..19c6040 --- /dev/null +++ b/src/main/generated/umc/spring/domain/mapping/QMemberPrefer.java @@ -0,0 +1,62 @@ +package umc.spring.domain.mapping; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QMemberPrefer is a Querydsl query type for MemberPrefer + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QMemberPrefer extends EntityPathBase { + + private static final long serialVersionUID = 1265463574L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QMemberPrefer memberPrefer = new QMemberPrefer("memberPrefer"); + + public final umc.spring.domain.common.QBaseEntity _super = new umc.spring.domain.common.QBaseEntity(this); + + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final umc.spring.domain.QFoodCategory foodCategory; + + public final NumberPath id = createNumber("id", Long.class); + + public final umc.spring.domain.QMember member; + + //inherited + public final DateTimePath updatedAt = _super.updatedAt; + + public QMemberPrefer(String variable) { + this(MemberPrefer.class, forVariable(variable), INITS); + } + + public QMemberPrefer(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QMemberPrefer(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QMemberPrefer(PathMetadata metadata, PathInits inits) { + this(MemberPrefer.class, metadata, inits); + } + + public QMemberPrefer(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.foodCategory = inits.isInitialized("foodCategory") ? new umc.spring.domain.QFoodCategory(forProperty("foodCategory")) : null; + this.member = inits.isInitialized("member") ? new umc.spring.domain.QMember(forProperty("member")) : null; + } + +} + diff --git a/src/main/java/umc/spring/Application.java b/src/main/java/umc/spring/Application.java index 5bc54b2..dec9166 100644 --- a/src/main/java/umc/spring/Application.java +++ b/src/main/java/umc/spring/Application.java @@ -6,7 +6,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import umc.spring.service.RestaurantService.RestaurantQueryService; +import umc.spring.service.StoreService.StoreQueryService; import static org.apache.commons.lang3.BooleanUtils.forEach; @@ -21,18 +21,18 @@ public static void main(String[] args) { @Bean public CommandLineRunner run(ApplicationContext context) { return args -> { - RestaurantQueryService restaurantService = context.getBean(RestaurantQueryService.class); + StoreQueryService storeService = context.getBean(StoreQueryService.class); // 파라미터 값 설정 String name = "요아정"; - Integer score = 4; + Float score = 4.0f; // 쿼리 메서드 호출 및 쿼리 문자열과 파라미터 출력 - System.out.println("Executing findRestaurantsByNameAndScore with parameters:"); + System.out.println("Executing findStoresByNameAndScore with parameters:"); System.out.println("Name: " + name); System.out.println("Score: " + score); - restaurantService.findRestaurantsByNameAndScore(name, score) + storeService.findStoresByNameAndScore(name, score) .forEach(System.out::println); }; }; diff --git a/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java b/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java index a8bf955..5038a63 100644 --- a/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java @@ -3,13 +3,11 @@ import lombok.AllArgsConstructor; import lombok.Getter; import org.springframework.http.HttpStatus; -import umc.spring.apiPayload.code.BaseCode; import umc.spring.apiPayload.code.BaseErrorCode; import umc.spring.apiPayload.code.ErrorReasonDTO; @Getter @AllArgsConstructor - public enum ErrorStatus implements BaseErrorCode { // 가장 일반적인 응답 @@ -29,6 +27,7 @@ public enum ErrorStatus implements BaseErrorCode { // For test TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP4001", "이거는 테스트"); + private final HttpStatus httpStatus; private final String code; private final String message; diff --git a/src/main/java/umc/spring/apiPayload/Exception/ExceptionAdvice.java b/src/main/java/umc/spring/apiPayload/exception/ExceptionAdvice.java similarity index 99% rename from src/main/java/umc/spring/apiPayload/Exception/ExceptionAdvice.java rename to src/main/java/umc/spring/apiPayload/exception/ExceptionAdvice.java index d076a9e..6d16558 100644 --- a/src/main/java/umc/spring/apiPayload/Exception/ExceptionAdvice.java +++ b/src/main/java/umc/spring/apiPayload/exception/ExceptionAdvice.java @@ -1,4 +1,4 @@ -package umc.spring.apiPayload.Exception; +package umc.spring.apiPayload.exception; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ConstraintViolationException; @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Optional; +@Slf4j @RestControllerAdvice(annotations = {RestController.class}) public class ExceptionAdvice extends ResponseEntityExceptionHandler { @@ -115,3 +116,4 @@ private ResponseEntity handleExceptionInternalConstraint(Exception e, Er ); } } + diff --git a/src/main/java/umc/spring/apiPayload/Exception/GeneralException.java b/src/main/java/umc/spring/apiPayload/exception/GeneralException.java similarity index 58% rename from src/main/java/umc/spring/apiPayload/Exception/GeneralException.java rename to src/main/java/umc/spring/apiPayload/exception/GeneralException.java index a55bcd6..b9f47a3 100644 --- a/src/main/java/umc/spring/apiPayload/Exception/GeneralException.java +++ b/src/main/java/umc/spring/apiPayload/exception/GeneralException.java @@ -1,17 +1,16 @@ -package umc.spring.apiPayload.Exception; +package umc.spring.apiPayload.exception; +import lombok.AllArgsConstructor; +import lombok.Getter; import umc.spring.apiPayload.code.BaseErrorCode; import umc.spring.apiPayload.code.ErrorReasonDTO; -public class GeneralException extends RuntimeException{ +@Getter +@AllArgsConstructor +public class GeneralException extends RuntimeException { private BaseErrorCode code; - public GeneralException(BaseErrorCode errorCode) { - super(errorCode.getReason().getMessage()); - this.code = errorCode; - } - public ErrorReasonDTO getErrorReason() { return this.code.getReason(); } diff --git a/src/main/java/umc/spring/apiPayload/Exception/handler/TempHandler.java b/src/main/java/umc/spring/apiPayload/exception/handler/TempHandler.java similarity index 63% rename from src/main/java/umc/spring/apiPayload/Exception/handler/TempHandler.java rename to src/main/java/umc/spring/apiPayload/exception/handler/TempHandler.java index c87628d..57c380e 100644 --- a/src/main/java/umc/spring/apiPayload/Exception/handler/TempHandler.java +++ b/src/main/java/umc/spring/apiPayload/exception/handler/TempHandler.java @@ -1,7 +1,7 @@ -package umc.spring.apiPayload.Exception.handler; +package umc.spring.apiPayload.exception.handler; -import umc.spring.apiPayload.Exception.GeneralException; import umc.spring.apiPayload.code.BaseErrorCode; +import umc.spring.apiPayload.exception.GeneralException; public class TempHandler extends GeneralException { diff --git a/src/main/java/umc/spring/domain/FoodCategory.java b/src/main/java/umc/spring/domain/FoodCategory.java new file mode 100644 index 0000000..6961a0b --- /dev/null +++ b/src/main/java/umc/spring/domain/FoodCategory.java @@ -0,0 +1,29 @@ +package umc.spring.domain; + +import jakarta.persistence.*; +import lombok.*; +import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.mapping.MemberMission; +import umc.spring.domain.mapping.MemberPrefer; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor + +public class FoodCategory extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 15) + private String name; + + @OneToMany(mappedBy = "foodCategory", cascade = CascadeType.ALL) + private List memberPreferList = new ArrayList<>(); +} diff --git a/src/main/java/umc/spring/domain/Member.java b/src/main/java/umc/spring/domain/Member.java index 22b2a7b..56e451a 100644 --- a/src/main/java/umc/spring/domain/Member.java +++ b/src/main/java/umc/spring/domain/Member.java @@ -4,7 +4,11 @@ import lombok.*; import umc.spring.domain.common.BaseEntity; import umc.spring.domain.enums.Gender; -import umc.spring.domain.enums.Status; +import umc.spring.domain.enums.MemberStatus; +import umc.spring.domain.enums.SocialType; +import umc.spring.domain.mapping.MemberAgree; +import umc.spring.domain.mapping.MemberMission; +import umc.spring.domain.mapping.MemberPrefer; import java.time.LocalDate; import java.util.ArrayList; @@ -24,30 +28,40 @@ public class Member extends BaseEntity { @Column(nullable = false, length = 20) private String name; - @Column(nullable = false, length = 20) - private LocalDate birth; - - @Column(nullable = false, length = 100) + @Column(nullable = false, length = 40) private String address; - @Column(nullable = false, length = 100) - private String favoriteFood; - - private LocalDate inactiveDate; - - private Integer point; + @Column(nullable = false, length = 40) + private String specAddress; @Enumerated(EnumType.STRING) @Column(columnDefinition = "VARCHAR(10)") private Gender gender; @Enumerated(EnumType.STRING) - @Column(columnDefinition = "VARCHAR(10) DEFAULT 'ACTIVE'") - private Status status; + @Column(columnDefinition = "VARCHAR(10)") + private SocialType SocialType; + + @Enumerated(EnumType.STRING) + @Column(columnDefinition = "VARCHAR(15) DEFAULT 'ACTIVE'") + private MemberStatus status; + + private LocalDate inactiveDate; + + @Column(nullable = false, length = 50) + private String email; + + private Integer point; + + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) + private List memberAgreeList = new ArrayList<>(); + + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) + private List memberPreferList = new ArrayList<>(); @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) - private List MissionList = new ArrayList<>(); + private List reviewList = new ArrayList<>(); @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) - private List ReviewList = new ArrayList<>(); + private List memberMissionList = new ArrayList<>(); } diff --git a/src/main/java/umc/spring/domain/Mission.java b/src/main/java/umc/spring/domain/Mission.java index 5817ee6..bf230d4 100644 --- a/src/main/java/umc/spring/domain/Mission.java +++ b/src/main/java/umc/spring/domain/Mission.java @@ -2,8 +2,10 @@ import jakarta.persistence.*; import lombok.*; -import umc.spring.domain.enums.Status; +import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.mapping.MemberMission; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -12,32 +14,23 @@ @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor -public class Mission { +public class Mission extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private boolean isSuccess; + private Integer reward; - @Column(nullable = false, length = 100) - private String content; + private LocalDate deadline; - private Integer code; + @Column(nullable = false, length = 200) + private String missionSpec; - @Enumerated(EnumType.STRING) - @Column(columnDefinition = "VARCHAR(10) DEFAULT 'ACTIVE'") - private Status status; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id") + private Store store; - @ManyToOne - @JoinColumn(name = "member_id") - private Member member; - - @ManyToOne - @JoinColumn(name = "region_id") - private Region region; - - @ManyToOne - @JoinColumn(name = "restaurant_id") - private Restaurant restaurant; + @OneToMany(mappedBy = "mission", cascade = CascadeType.ALL) + private List memberMissionList = new ArrayList<>(); } diff --git a/src/main/java/umc/spring/domain/Region.java b/src/main/java/umc/spring/domain/Region.java index 045f350..9e05d32 100644 --- a/src/main/java/umc/spring/domain/Region.java +++ b/src/main/java/umc/spring/domain/Region.java @@ -3,6 +3,7 @@ import jakarta.persistence.*; import lombok.*; import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.mapping.MemberMission; import java.util.ArrayList; import java.util.List; @@ -21,16 +22,7 @@ public class Region extends BaseEntity { @Column(nullable = false, length = 20) private String name; - private Integer successNumber; - - private boolean isRewarded; - @OneToMany(mappedBy = "region", cascade = CascadeType.ALL) - private List MissionList = new ArrayList<>(); + private List storeList = new ArrayList<>(); - @OneToMany(mappedBy = "region", cascade = CascadeType.ALL) - private List ReviewList = new ArrayList<>(); - - @OneToMany(mappedBy = "region", cascade = CascadeType.ALL) - private List RestaurantList = new ArrayList<>(); } diff --git a/src/main/java/umc/spring/domain/Review.java b/src/main/java/umc/spring/domain/Review.java index 200c3e9..35be880 100644 --- a/src/main/java/umc/spring/domain/Review.java +++ b/src/main/java/umc/spring/domain/Review.java @@ -3,6 +3,7 @@ import jakarta.persistence.*; import lombok.*; import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.mapping.MemberMission; import java.util.ArrayList; import java.util.List; @@ -18,20 +19,17 @@ public class Review extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private Integer score; - @Column(nullable = false, length = 200) - private String content; + private String title; + + private Float score; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; - @ManyToOne - @JoinColumn(name = "region_id") - private Region region; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "store_id") + private Store store; - @ManyToOne - @JoinColumn(name = "restaurant_id") - private Restaurant restaurant; } diff --git a/src/main/java/umc/spring/domain/Restaurant.java b/src/main/java/umc/spring/domain/Store.java similarity index 64% rename from src/main/java/umc/spring/domain/Restaurant.java rename to src/main/java/umc/spring/domain/Store.java index fe02510..0939595 100644 --- a/src/main/java/umc/spring/domain/Restaurant.java +++ b/src/main/java/umc/spring/domain/Store.java @@ -3,6 +3,7 @@ import jakarta.persistence.*; import lombok.*; import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.mapping.MemberMission; import java.util.ArrayList; import java.util.List; @@ -12,33 +13,30 @@ @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor -public class Restaurant extends BaseEntity { +public class Store extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = false, length = 100) - private String address; - - private Integer score; - - @Column(nullable = false, length = 20) + @Column(nullable = false, length = 50) private String name; - @OneToMany(mappedBy = "restaurant", cascade = CascadeType.ALL) - private List ReviewList = new ArrayList<>(); + @Column(nullable = false, length = 50) + private String address; - @OneToMany(mappedBy = "restaurant", cascade = CascadeType.ALL) - private List Mission = new ArrayList<>(); + private Float score; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "region_id") private Region region; + @OneToMany(mappedBy = "store", cascade = CascadeType.ALL) + private List reviewList = new ArrayList<>(); + @Override public String toString() { - return "Restaurant{" + + return "Store{" + "id=" + id + ", name='" + name + '\'' + ", address='" + address + '\'' + diff --git a/src/main/java/umc/spring/domain/Terms.java b/src/main/java/umc/spring/domain/Terms.java new file mode 100644 index 0000000..5c720e9 --- /dev/null +++ b/src/main/java/umc/spring/domain/Terms.java @@ -0,0 +1,32 @@ +package umc.spring.domain; + +import jakarta.persistence.*; +import lombok.*; +import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.mapping.MemberAgree; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class Terms extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, length = 20) + private String title; + + @Column(nullable = false, length = 200) + private String body; + + private Boolean optional; + + @OneToMany(mappedBy = "terms", cascade = CascadeType.ALL) + private List memberAgreeList = new ArrayList<>(); +} diff --git a/src/main/java/umc/spring/domain/enums/Status.java b/src/main/java/umc/spring/domain/enums/MemberStatus.java similarity index 67% rename from src/main/java/umc/spring/domain/enums/Status.java rename to src/main/java/umc/spring/domain/enums/MemberStatus.java index 7e99776..939ac6d 100644 --- a/src/main/java/umc/spring/domain/enums/Status.java +++ b/src/main/java/umc/spring/domain/enums/MemberStatus.java @@ -1,5 +1,6 @@ package umc.spring.domain.enums; -public enum Status { +public enum MemberStatus { + ACTIVE, INACTIVE } diff --git a/src/main/java/umc/spring/domain/enums/MissionStatus.java b/src/main/java/umc/spring/domain/enums/MissionStatus.java new file mode 100644 index 0000000..5c2ad91 --- /dev/null +++ b/src/main/java/umc/spring/domain/enums/MissionStatus.java @@ -0,0 +1,6 @@ +package umc.spring.domain.enums; + +public enum MissionStatus { + + CHALLENGING, COMPLETE +} diff --git a/src/main/java/umc/spring/domain/enums/SocialType.java b/src/main/java/umc/spring/domain/enums/SocialType.java new file mode 100644 index 0000000..4a5e993 --- /dev/null +++ b/src/main/java/umc/spring/domain/enums/SocialType.java @@ -0,0 +1,6 @@ +package umc.spring.domain.enums; + +public enum SocialType { + + KAKAO, GOOGLE, NAVER, APPLE +} diff --git a/src/main/java/umc/spring/domain/mapping/MemberAgree.java b/src/main/java/umc/spring/domain/mapping/MemberAgree.java new file mode 100644 index 0000000..60b370b --- /dev/null +++ b/src/main/java/umc/spring/domain/mapping/MemberAgree.java @@ -0,0 +1,27 @@ +package umc.spring.domain.mapping; + +import jakarta.persistence.*; +import lombok.*; +import umc.spring.domain.Member; +import umc.spring.domain.Terms; +import umc.spring.domain.common.BaseEntity; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class MemberAgree extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "terms_id") + private Terms terms; +} diff --git a/src/main/java/umc/spring/domain/mapping/MemberMission.java b/src/main/java/umc/spring/domain/mapping/MemberMission.java new file mode 100644 index 0000000..67b6cbc --- /dev/null +++ b/src/main/java/umc/spring/domain/mapping/MemberMission.java @@ -0,0 +1,33 @@ +package umc.spring.domain.mapping; + +import jakarta.persistence.*; +import lombok.*; +import umc.spring.domain.Member; +import umc.spring.domain.Mission; +import umc.spring.domain.Terms; +import umc.spring.domain.common.BaseEntity; +import umc.spring.domain.enums.MissionStatus; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class MemberMission extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Enumerated(EnumType.STRING) + private MissionStatus status; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "mission_id") + private Mission mission; + +} diff --git a/src/main/java/umc/spring/domain/mapping/MemberPrefer.java b/src/main/java/umc/spring/domain/mapping/MemberPrefer.java new file mode 100644 index 0000000..ee766b9 --- /dev/null +++ b/src/main/java/umc/spring/domain/mapping/MemberPrefer.java @@ -0,0 +1,27 @@ +package umc.spring.domain.mapping; + +import jakarta.persistence.*; +import lombok.*; +import umc.spring.domain.FoodCategory; +import umc.spring.domain.Member; +import umc.spring.domain.common.BaseEntity; + +@Entity +@Getter +@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +public class MemberPrefer extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "foodCategory_id") + private FoodCategory foodCategory; +} diff --git a/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepository.java b/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepository.java deleted file mode 100644 index 41035d7..0000000 --- a/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package umc.spring.repository.RestaurantRepository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import umc.spring.domain.Restaurant; - -@Repository -public interface RestaurantRepository extends JpaRepository, RestaurantRepositoryCustom{ -} diff --git a/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryCustom.java b/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryCustom.java deleted file mode 100644 index 0012f41..0000000 --- a/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryCustom.java +++ /dev/null @@ -1,8 +0,0 @@ -package umc.spring.repository.RestaurantRepository; - - -import umc.spring.domain.Restaurant; -import java.util.List; -public interface RestaurantRepositoryCustom { - List dynamicQueryWithBooleanBuilder(String name, Integer score); -} diff --git a/src/main/java/umc/spring/repository/StoreRepository/StoreRepository.java b/src/main/java/umc/spring/repository/StoreRepository/StoreRepository.java new file mode 100644 index 0000000..38a81b8 --- /dev/null +++ b/src/main/java/umc/spring/repository/StoreRepository/StoreRepository.java @@ -0,0 +1,7 @@ +package umc.spring.repository.StoreRepository; + +import org.springframework.data.jpa.repository.JpaRepository; +import umc.spring.domain.Store; + +public interface StoreRepository extends JpaRepository, StoreRepositoryCustom { +} diff --git a/src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryCustom.java b/src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryCustom.java new file mode 100644 index 0000000..934730b --- /dev/null +++ b/src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryCustom.java @@ -0,0 +1,9 @@ +package umc.spring.repository.StoreRepository; + +import umc.spring.domain.Store; + +import java.util.List; + +public interface StoreRepositoryCustom { + List dynamicQueryWithBooleanBuilder(String name, Float score); +} diff --git a/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryImpl.java b/src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryImpl.java similarity index 51% rename from src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryImpl.java rename to src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryImpl.java index 088d7f7..ab59094 100644 --- a/src/main/java/umc/spring/repository/RestaurantRepository/RestaurantRepositoryImpl.java +++ b/src/main/java/umc/spring/repository/StoreRepository/StoreRepositoryImpl.java @@ -1,34 +1,35 @@ -package umc.spring.repository.RestaurantRepository; +package umc.spring.repository.StoreRepository; import com.querydsl.core.BooleanBuilder; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; -import umc.spring.domain.QRestaurant; -import umc.spring.domain.Restaurant; +import umc.spring.domain.QStore; +import umc.spring.domain.Store; import java.util.List; + @Repository @RequiredArgsConstructor -public class RestaurantRepositoryImpl implements RestaurantRepositoryCustom{ +public class StoreRepositoryImpl implements StoreRepositoryCustom { private final JPAQueryFactory jpaQueryFactory; - private final QRestaurant restaurant = QRestaurant.restaurant; + private final QStore store = QStore.store; @Override - public List dynamicQueryWithBooleanBuilder(String name, Integer score) { + public List dynamicQueryWithBooleanBuilder(String name, Float score) { BooleanBuilder predicate = new BooleanBuilder(); if (name != null) { - predicate.and(restaurant.name.eq(name)); + predicate.and(store.name.eq(name)); } if (score != null) { - predicate.and(restaurant.score.goe(4.0f)); + predicate.and(store.score.goe(4.0f)); } return jpaQueryFactory - .selectFrom(restaurant) + .selectFrom(store) .where(predicate) .fetch(); } diff --git a/src/main/java/umc/spring/service/RestaurantService/RestaurantQueryService.java b/src/main/java/umc/spring/service/RestaurantService/RestaurantQueryService.java deleted file mode 100644 index 2c11d75..0000000 --- a/src/main/java/umc/spring/service/RestaurantService/RestaurantQueryService.java +++ /dev/null @@ -1,12 +0,0 @@ -package umc.spring.service.RestaurantService; - -import umc.spring.domain.Restaurant; - -import java.util.List; -import java.util.Optional; - -public interface RestaurantQueryService { - - Optional findRestaurant(Long id); - List findRestaurantsByNameAndScore(String name, Integer score); -} diff --git a/src/main/java/umc/spring/service/RestaurantService/RestaurantQueryServiceImpl.java b/src/main/java/umc/spring/service/RestaurantService/RestaurantQueryServiceImpl.java deleted file mode 100644 index 0d9291a..0000000 --- a/src/main/java/umc/spring/service/RestaurantService/RestaurantQueryServiceImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package umc.spring.service.RestaurantService; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import umc.spring.domain.Restaurant; -import umc.spring.repository.RestaurantRepository.RestaurantRepository; - -import org.springframework.transaction.annotation.Transactional; -import java.util.List; -import java.util.Optional; - -import static umc.spring.domain.QRestaurant.restaurant; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class RestaurantQueryServiceImpl implements RestaurantQueryService{ - - private final RestaurantRepository restaurantRepository; - - @Override - public Optional findRestaurant(Long id) { - return restaurantRepository.findById(id); - } - - @Override - public List findRestaurantsByNameAndScore(String name, Integer score) { - List filteredRestaurants = restaurantRepository.dynamicQueryWithBooleanBuilder(name, score); - - filteredRestaurants.forEach(restaurant -> System.out.println("Restaurant: " + restaurant)); - - return filteredRestaurants; - } -} diff --git a/src/main/java/umc/spring/service/StoreService/StoreQueryService.java b/src/main/java/umc/spring/service/StoreService/StoreQueryService.java new file mode 100644 index 0000000..1534b7b --- /dev/null +++ b/src/main/java/umc/spring/service/StoreService/StoreQueryService.java @@ -0,0 +1,12 @@ +package umc.spring.service.StoreService; + +import umc.spring.domain.Store; + +import java.util.List; +import java.util.Optional; + +public interface StoreQueryService { + + Optional findStore(Long id); + List findStoresByNameAndScore(String name, Float score); +} diff --git a/src/main/java/umc/spring/service/StoreService/StoreQueryServiceImpl.java b/src/main/java/umc/spring/service/StoreService/StoreQueryServiceImpl.java new file mode 100644 index 0000000..0e4b243 --- /dev/null +++ b/src/main/java/umc/spring/service/StoreService/StoreQueryServiceImpl.java @@ -0,0 +1,32 @@ +package umc.spring.service.StoreService; + +import org.springframework.transaction.annotation.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import umc.spring.domain.Store; +import umc.spring.repository.StoreRepository.StoreRepository; + +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class StoreQueryServiceImpl implements StoreQueryService{ + + private final StoreRepository storeRepository; + + @Override + public Optional findStore(Long id) { + return storeRepository.findById(id); + } + + @Override + public List findStoresByNameAndScore(String name, Float score) { + List filteredStores = storeRepository.dynamicQueryWithBooleanBuilder(name, score); + + filteredStores.forEach(store -> System.out.println("Store: " + store)); + + return filteredStores; + } +} diff --git a/src/main/java/umc/spring/service/TempService/TempQueryServiceImpl.java b/src/main/java/umc/spring/service/TempService/TempCommandQueryImpl.java similarity index 74% rename from src/main/java/umc/spring/service/TempService/TempQueryServiceImpl.java rename to src/main/java/umc/spring/service/TempService/TempCommandQueryImpl.java index 3b38bfd..3e0ec07 100644 --- a/src/main/java/umc/spring/service/TempService/TempQueryServiceImpl.java +++ b/src/main/java/umc/spring/service/TempService/TempCommandQueryImpl.java @@ -2,12 +2,12 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import umc.spring.apiPayload.Exception.handler.TempHandler; import umc.spring.apiPayload.code.status.ErrorStatus; +import umc.spring.apiPayload.exception.handler.TempHandler; @Service @RequiredArgsConstructor -public class TempQueryServiceImpl implements TempQueryService { +public class TempCommandQueryImpl implements TempQueryService{ @Override public void CheckFlag(Integer flag) { diff --git a/src/main/java/umc/spring/service/TempService/TempQueryService.java b/src/main/java/umc/spring/service/TempService/TempQueryService.java index af8146c..de8e0f0 100644 --- a/src/main/java/umc/spring/service/TempService/TempQueryService.java +++ b/src/main/java/umc/spring/service/TempService/TempQueryService.java @@ -1,5 +1,6 @@ package umc.spring.service.TempService; public interface TempQueryService { + void CheckFlag(Integer flag); } diff --git a/src/main/java/umc/spring/web/controller/TempRestController.java b/src/main/java/umc/spring/web/controller/TempRestController.java index 17bf5df..f7849fd 100644 --- a/src/main/java/umc/spring/web/controller/TempRestController.java +++ b/src/main/java/umc/spring/web/controller/TempRestController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import umc.spring.apiPayload.ApiResponse; +import umc.spring.apiPayload.code.ReasonDTO; import umc.spring.converter.TempConverter; import umc.spring.service.TempService.TempQueryService; import umc.spring.web.dto.TempResponse; @@ -23,7 +24,6 @@ public ApiResponse testAPI(){ return ApiResponse.onSuccess(TempConverter.toTempTestDTO()); } - @GetMapping("/exception") public ApiResponse exceptionAPI(@RequestParam Integer flag){ tempQueryService.CheckFlag(flag); diff --git a/src/main/java/umc/spring/web/dto/TempRequest.java b/src/main/java/umc/spring/web/dto/TempRequest.java deleted file mode 100644 index 6d3ff3f..0000000 --- a/src/main/java/umc/spring/web/dto/TempRequest.java +++ /dev/null @@ -1,6 +0,0 @@ -package umc.spring.web.dto; - -public class TempRequest { - - -} diff --git a/src/main/resources/Application.yml b/src/main/resources/Application.yml index e4bb12f..be57bf4 100644 --- a/src/main/resources/Application.yml +++ b/src/main/resources/Application.yml @@ -1,7 +1,7 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/umc7th + url: jdbc:mysql://localhost:3306/study username: root password: ej318103 sql: diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e4bb12f..be57bf4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,7 +1,7 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/umc7th + url: jdbc:mysql://localhost:3306/study username: root password: ej318103 sql: From e29fdb1cc3f07f0cd3f292447d336f0c13ec7978 Mon Sep 17 00:00:00 2001 From: ceunjinn Date: Sat, 7 Dec 2024 23:53:28 +0900 Subject: [PATCH 2/2] mission --- .gradle/8.10.2/checksums/checksums.lock | Bin 17 -> 17 bytes .gradle/8.10.2/checksums/md5-checksums.bin | Bin 31197 -> 32997 bytes .gradle/8.10.2/checksums/sha1-checksums.bin | Bin 75299 -> 81725 bytes .gradle/8.10.2/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes build.gradle | 10 +++ .../generated/umc/spring/domain/QMember.java | 4 + .../apiPayload/code/status/ErrorStatus.java | 3 + .../handler/FoodCategoryHandler.java | 11 +++ .../Security/CustomOAuth2UserService.java | 65 ++++++++++++++++ .../Security/CustomUserDetailsService.java | 28 +++++++ .../config/Security/SecurityConfig.java | 46 ++++++++++++ .../umc/spring/converter/MemberConverter.java | 47 ++++++++++++ .../converter/MemberPreferConverter.java | 20 +++++ src/main/java/umc/spring/domain/Member.java | 17 +++++ .../java/umc/spring/domain/enums/Gender.java | 2 +- .../java/umc/spring/domain/enums/Role.java | 5 ++ .../spring/domain/mapping/MemberPrefer.java | 13 +++- .../repository/FoodCategoryRepository.java | 7 ++ .../spring/repository/MemberRepository.java | 10 +++ .../MemberService/MemberCommandService.java | 11 +++ .../MemberCommandServiceImpl.java | 50 ++++++++++++ .../web/controller/MemberRestController.java | 28 +++++++ .../web/controller/MemberViewController.java | 60 +++++++++++++++ .../umc/spring/web/dto/MemberRequestDTO.java | 41 ++++++++++ .../umc/spring/web/dto/MemberResponseDTO.java | 20 +++++ .../java/umc/spring/web/dto/classJoinDto.java | 18 +++++ src/main/resources/Application.yml | 20 ++++- src/main/resources/application.yml | 20 ++++- src/main/resources/templates/admin.html | 10 +++ src/main/resources/templates/home.html | 17 +++++ src/main/resources/templates/login.html | 30 ++++++++ src/main/resources/templates/signup.html | 71 ++++++++++++++++++ 32 files changed, 680 insertions(+), 4 deletions(-) create mode 100644 src/main/java/umc/spring/apiPayload/exception/handler/FoodCategoryHandler.java create mode 100644 src/main/java/umc/spring/config/Security/CustomOAuth2UserService.java create mode 100644 src/main/java/umc/spring/config/Security/CustomUserDetailsService.java create mode 100644 src/main/java/umc/spring/config/Security/SecurityConfig.java create mode 100644 src/main/java/umc/spring/converter/MemberConverter.java create mode 100644 src/main/java/umc/spring/converter/MemberPreferConverter.java create mode 100644 src/main/java/umc/spring/domain/enums/Role.java create mode 100644 src/main/java/umc/spring/repository/FoodCategoryRepository.java create mode 100644 src/main/java/umc/spring/repository/MemberRepository.java create mode 100644 src/main/java/umc/spring/service/MemberService/MemberCommandService.java create mode 100644 src/main/java/umc/spring/service/MemberService/MemberCommandServiceImpl.java create mode 100644 src/main/java/umc/spring/web/controller/MemberRestController.java create mode 100644 src/main/java/umc/spring/web/controller/MemberViewController.java create mode 100644 src/main/java/umc/spring/web/dto/MemberRequestDTO.java create mode 100644 src/main/java/umc/spring/web/dto/MemberResponseDTO.java create mode 100644 src/main/java/umc/spring/web/dto/classJoinDto.java create mode 100644 src/main/resources/templates/admin.html create mode 100644 src/main/resources/templates/home.html create mode 100644 src/main/resources/templates/login.html create mode 100644 src/main/resources/templates/signup.html diff --git a/.gradle/8.10.2/checksums/checksums.lock b/.gradle/8.10.2/checksums/checksums.lock index 27d9248541befda5fe798e54a580da46874d314b..334ca6b5f2735eb0b23650aeb1b7a9805372c2a4 100644 GIT binary patch literal 17 UcmZSXC{KUU$Y}hB0Ss7#05UQJ82|tP literal 17 UcmZSXC{KUU$Y}hB0SuVa05XIGYybcN diff --git a/.gradle/8.10.2/checksums/md5-checksums.bin b/.gradle/8.10.2/checksums/md5-checksums.bin index a99b77a6437b37a0281f081247fc0ec06002c00d..0175bf73cf730c4da282739859b4a94b5e288042 100644 GIT binary patch delta 2555 zcmZvd3pA8z7{_O(G`Y^lG`VCZj2M?eqDb1N$R)Y1qEf5ajiYi&xsQ>{rYQSjC$))^ z>a0!8rj(LvI#xzeX-R6d+Ab2YqP6cg@7M0x8P7T2`y*%&NJ3<~1P%4*b zQOE`&TdlcdEW111<`~D)og}pc9YHz`L0U=b zut;YoRv7u`DgUWgnS?k?l%Zoq!G0EJ2;Pn4-a~3~u&6?}noMhOR*t2Ne+jx71hMpK zhMcODLYJ3>qa}!C323_0v11)Ic}PoTg10Pt+J;=)de5*_q$Mf>=0bZ~50$F&he{06 zl8%YiFXWK1b|c|Nt3uOGr1Go5F1;44dqClR;tJm(Bqlcju6`=k=Tv*U=U(}HLIj{p zUx>Z@6r2@xu8R%q%jaBQ3>5 z;Xt?=<*<{O56o9OnhkN7eh*tFT6&Msa~MXL=Rh0-s~By%1jJK}MkYpPa_)Kmeu zVqS@b4vkndcAkt!V)8f$;_n7&c+;cFHI1*=*x=kO{;Mb zNlw2&dZGiUu<+)@eyTB#b-b2BMDYLOy#I;QdBI5ek4R5y6@9eOAyXFcF6oQsiFmFj z7W0?Dzf9nxk3ZNQV@KY^)o^FpHth=%md!;Hi42Mxy@*v+ihxcQ|0g&h=cwsQ0k`d5 zmKyX-`y4`q_kQRJjXnhj8NzzdiT(C%LUexQic%-#gnBMQd=3F-s1E<`t8T5!8`Q!S z-|RTz9e!7x`16c397!cxKAvxsnEdJh*B)sfS8@;8 zJ|bEDA*MKlAU;4(K72HzzlLF5 zSsN$xDGHlj#Mzb+VXKgj+HCliDI{vu=W^Q0*2(R+f*$)vQ2Y=Pgdt+4JvHq7t8J-u z@PYKolQt5^=>&pUiW6{w==f&HBq>_d?bccR;FbyIRq%`zD3T(r=9f?sMY22*Q9E$J zr6}_ks%vn*+0vu1P2f>$HSa)#`Z9TfyRvkYvEVFCmn9AjIKa#5K?oPF6K-Fh2E$wE zeAoKe>2s##)rwD*o2nvL6FzX(xM^>LgG}jt6Ah7jj1@eNwa53RIJm(J5HExaN!&Dy z;2=Xto^B~%K5}lb?+=I@SniDuL#w3(_lN646Urk71<`Y-)*lQrygcSVloU!JR?av= zBAH!>gG`cD9c>B%-%gS!!zQOFfO%Y6R{OA~6d=*@ua*pvy@-)2=Ktni!o-G|r6UT> z2>Gakka;Y5gnMvswW~wRzL;e#z`<_^n;>9I;RW08)xZNESW57TFz$%B*t%ZQbmXb@i|joCyzAQx-B-3>Bwj2Kd*{U z=faB?FUx|5k|@nE5o_8N70)+iyM;_+zvjP#;1QJ)UPM{a+fn914dU^x&(-X{@$qol zqmJPLc*{zWFoe+G%9ll|c4O^2N#gw!7@2deS@8xzyh4N`-cd4hpNzU}kL?|17C))W}~1PiATVX1)#jaYf&+MMpj7pFEl8B_bi zlRb-JIru~@@iv8K_3xJO|NEFs3??6#rG9s`3HfDy?g)w delta 171 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 z { public final StringPath name = createString("name"); + public final StringPath password = createString("password"); + public final NumberPath point = createNumber("point", Integer.class); public final ListPath reviewList = this.createList("reviewList", Review.class, QReview.class, PathInits.DIRECT2); + public final EnumPath role = createEnum("role", umc.spring.domain.enums.Role.class); + public final EnumPath SocialType = createEnum("SocialType", umc.spring.domain.enums.SocialType.class); public final StringPath specAddress = createString("specAddress"); diff --git a/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java b/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java index 5038a63..4b10625 100644 --- a/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java +++ b/src/main/java/umc/spring/apiPayload/code/status/ErrorStatus.java @@ -24,6 +24,9 @@ public enum ErrorStatus implements BaseErrorCode { // 예시,,, ARTICLE_NOT_FOUND(HttpStatus.NOT_FOUND, "ARTICLE4001", "게시글이 없습니다."), + // 음식 카테고리 관련 에러 + FOOD_CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "FOOD4001", "음식 카테고리를 찾을 수 없습니다."), + // For test TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP4001", "이거는 테스트"); diff --git a/src/main/java/umc/spring/apiPayload/exception/handler/FoodCategoryHandler.java b/src/main/java/umc/spring/apiPayload/exception/handler/FoodCategoryHandler.java new file mode 100644 index 0000000..54ae3f2 --- /dev/null +++ b/src/main/java/umc/spring/apiPayload/exception/handler/FoodCategoryHandler.java @@ -0,0 +1,11 @@ +package umc.spring.apiPayload.exception.handler; + +import umc.spring.apiPayload.code.BaseErrorCode; +import umc.spring.apiPayload.exception.GeneralException; + +public class FoodCategoryHandler extends GeneralException { + + public FoodCategoryHandler(BaseErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/umc/spring/config/Security/CustomOAuth2UserService.java b/src/main/java/umc/spring/config/Security/CustomOAuth2UserService.java new file mode 100644 index 0000000..5fd54bc --- /dev/null +++ b/src/main/java/umc/spring/config/Security/CustomOAuth2UserService.java @@ -0,0 +1,65 @@ +package umc.spring.config.Security; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +import org.springframework.security.oauth2.core.OAuth2AuthenticationException; +import org.springframework.security.oauth2.core.user.DefaultOAuth2User; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.stereotype.Service; +import umc.spring.domain.Member; +import umc.spring.domain.enums.Gender; +import umc.spring.domain.enums.Role; +import umc.spring.repository.MemberRepository; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class CustomOAuth2UserService extends DefaultOAuth2UserService { + + private final MemberRepository memberRepository; + private final PasswordEncoder passwordEncoder; + + @Override + public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { + OAuth2User oAuth2User = super.loadUser(userRequest); + + Map attributes = oAuth2User.getAttributes(); + Map properties = (Map) attributes.get("properties"); + + String nickname = (String) properties.get("nickname"); + String email = nickname + "@kakao.com"; // 임시 이메일 생성 + + // 사용자 정보 저장 또는 업데이트 + Member member = saveOrUpdateUser(email, nickname); + + // 이메일을 Principal로 사용하기 위해 attributes 수정 + Map modifiedAttributes = new HashMap<>(attributes); + modifiedAttributes.put("email", email); + + return new DefaultOAuth2User( + oAuth2User.getAuthorities(), + modifiedAttributes, + "email" // email Principal로 설정 + ); + } + + private Member saveOrUpdateUser(String email, String nickname) { + Member member = memberRepository.findByEmail(email) + .orElse(Member.builder() + .email(email) + .name(nickname) + .password(passwordEncoder.encode("OAUTH_USER_" + UUID.randomUUID())) + .gender(Gender.NONE) // 기본값 설정 + .address("소셜로그인") // 기본값 설정 + .specAddress("소셜로그인") // 기본값 설정 + .role(Role.USER) + .build()); + + return memberRepository.save(member); + } +} diff --git a/src/main/java/umc/spring/config/Security/CustomUserDetailsService.java b/src/main/java/umc/spring/config/Security/CustomUserDetailsService.java new file mode 100644 index 0000000..8040906 --- /dev/null +++ b/src/main/java/umc/spring/config/Security/CustomUserDetailsService.java @@ -0,0 +1,28 @@ +package umc.spring.config.Security; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import umc.spring.domain.Member; +import umc.spring.repository.MemberRepository; + +@Service +@RequiredArgsConstructor +public class CustomUserDetailsService implements UserDetailsService { + + private final MemberRepository memberRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Member member = memberRepository.findByEmail(username) + .orElseThrow(() -> new UsernameNotFoundException("해당 이메일을 가진 유저가 존재하지 않습니다: " + username)); + + return org.springframework.security.core.userdetails.User + .withUsername(member.getEmail()) + .password(member.getPassword()) + .roles(member.getRole().name()) + .build(); + } +} diff --git a/src/main/java/umc/spring/config/Security/SecurityConfig.java b/src/main/java/umc/spring/config/Security/SecurityConfig.java new file mode 100644 index 0000000..21d57ac --- /dev/null +++ b/src/main/java/umc/spring/config/Security/SecurityConfig.java @@ -0,0 +1,46 @@ +package umc.spring.config.Security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@EnableWebSecurity +@Configuration +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests((requests) -> requests + .requestMatchers("/", "/home", "/signup", "/members/signup", "/css/**").permitAll() + .requestMatchers("/admin/**").hasRole("ADMIN") + .anyRequest().authenticated() + ) + .formLogin((form) -> form + .loginPage("/login") + .defaultSuccessUrl("/home", true) + .permitAll() + ) + .logout((logout) -> logout + .logoutUrl("/logout") + .logoutSuccessUrl("/login?logout") + .permitAll() + ) + .oauth2Login(oauth2 -> oauth2 + .loginPage("/login") + .defaultSuccessUrl("/home", true) + .permitAll() + ); + + return http.build(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/src/main/java/umc/spring/converter/MemberConverter.java b/src/main/java/umc/spring/converter/MemberConverter.java new file mode 100644 index 0000000..d852abc --- /dev/null +++ b/src/main/java/umc/spring/converter/MemberConverter.java @@ -0,0 +1,47 @@ +package umc.spring.converter; + +import umc.spring.domain.Member; +import umc.spring.domain.enums.Gender; +import umc.spring.web.dto.MemberRequestDTO; +import umc.spring.web.dto.MemberResponseDTO; + +import java.time.LocalDateTime; +import java.util.ArrayList; + +public class MemberConverter { + + public static MemberResponseDTO.JoinResultDTO toJoinResultDTO(Member member){ + return MemberResponseDTO.JoinResultDTO.builder() + .memberId(member.getId()) + .createdAt(LocalDateTime.now()) + .build(); + } + + public static Member toMember(MemberRequestDTO.JoinDto request){ + + Gender gender = null; + + switch (request.getGender()){ + case 1: + gender = Gender.MALE; + break; + case 2: + gender = Gender.FEMALE; + break; + case 3: + gender = Gender.NONE; + break; + } + + return Member.builder() + .name(request.getName()) + .email(request.getEmail()) // 추가된 코드 + .password(request.getPassword()) // 추가된 코드 + .gender(gender) + .address(request.getAddress()) + .specAddress(request.getSpecAddress()) + .role(request.getRole()) // 추가된 코드 + .memberPreferList(new ArrayList<>()) + .build(); + } +} diff --git a/src/main/java/umc/spring/converter/MemberPreferConverter.java b/src/main/java/umc/spring/converter/MemberPreferConverter.java new file mode 100644 index 0000000..28564da --- /dev/null +++ b/src/main/java/umc/spring/converter/MemberPreferConverter.java @@ -0,0 +1,20 @@ +package umc.spring.converter; + +import umc.spring.domain.FoodCategory; +import umc.spring.domain.mapping.MemberPrefer; + +import java.util.List; +import java.util.stream.Collectors; + +public class MemberPreferConverter { + + public static List toMemberPreferList(List foodCategoryList){ + + return foodCategoryList.stream() + .map(foodCategory -> + MemberPrefer.builder() + .foodCategory(foodCategory) + .build() + ).collect(Collectors.toList()); + } +} diff --git a/src/main/java/umc/spring/domain/Member.java b/src/main/java/umc/spring/domain/Member.java index 56e451a..899cfab 100644 --- a/src/main/java/umc/spring/domain/Member.java +++ b/src/main/java/umc/spring/domain/Member.java @@ -2,9 +2,13 @@ import jakarta.persistence.*; import lombok.*; +import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; import umc.spring.domain.common.BaseEntity; import umc.spring.domain.enums.Gender; import umc.spring.domain.enums.MemberStatus; +import umc.spring.domain.enums.Role; import umc.spring.domain.enums.SocialType; import umc.spring.domain.mapping.MemberAgree; import umc.spring.domain.mapping.MemberMission; @@ -19,6 +23,8 @@ @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor +@DynamicUpdate +@DynamicInsert public class Member extends BaseEntity { @Id @@ -51,6 +57,13 @@ public class Member extends BaseEntity { @Column(nullable = false, length = 50) private String email; + @Column(nullable = false) + private String password; + + @Enumerated(EnumType.STRING) + private Role role; + + @ColumnDefault("0") private Integer point; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) @@ -64,4 +77,8 @@ public class Member extends BaseEntity { @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) private List memberMissionList = new ArrayList<>(); + + public void encodePassword(String password) { + this.password = password; + } } diff --git a/src/main/java/umc/spring/domain/enums/Gender.java b/src/main/java/umc/spring/domain/enums/Gender.java index b74c14e..e2d4745 100644 --- a/src/main/java/umc/spring/domain/enums/Gender.java +++ b/src/main/java/umc/spring/domain/enums/Gender.java @@ -1,5 +1,5 @@ package umc.spring.domain.enums; public enum Gender { - MALE, FEMALE + MALE, FEMALE, NONE } diff --git a/src/main/java/umc/spring/domain/enums/Role.java b/src/main/java/umc/spring/domain/enums/Role.java new file mode 100644 index 0000000..61d3b50 --- /dev/null +++ b/src/main/java/umc/spring/domain/enums/Role.java @@ -0,0 +1,5 @@ +package umc.spring.domain.enums; + +public enum Role { + ADMIN, USER +} diff --git a/src/main/java/umc/spring/domain/mapping/MemberPrefer.java b/src/main/java/umc/spring/domain/mapping/MemberPrefer.java index ee766b9..d88ba3c 100644 --- a/src/main/java/umc/spring/domain/mapping/MemberPrefer.java +++ b/src/main/java/umc/spring/domain/mapping/MemberPrefer.java @@ -22,6 +22,17 @@ public class MemberPrefer extends BaseEntity { private Member member; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "foodCategory_id") + @JoinColumn(name = "category_id") private FoodCategory foodCategory; + + public void setMember(Member member){ + if(this.member != null) + member.getMemberPreferList().remove(this); + this.member = member; + member.getMemberPreferList().add(this); + } + + public void setFoodCategory(FoodCategory foodCategory){ + this.foodCategory = foodCategory; + } } diff --git a/src/main/java/umc/spring/repository/FoodCategoryRepository.java b/src/main/java/umc/spring/repository/FoodCategoryRepository.java new file mode 100644 index 0000000..b75fa21 --- /dev/null +++ b/src/main/java/umc/spring/repository/FoodCategoryRepository.java @@ -0,0 +1,7 @@ +package umc.spring.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import umc.spring.domain.FoodCategory; + +public interface FoodCategoryRepository extends JpaRepository { +} diff --git a/src/main/java/umc/spring/repository/MemberRepository.java b/src/main/java/umc/spring/repository/MemberRepository.java new file mode 100644 index 0000000..8758e98 --- /dev/null +++ b/src/main/java/umc/spring/repository/MemberRepository.java @@ -0,0 +1,10 @@ +package umc.spring.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import umc.spring.domain.Member; +import java.util.Optional; + +public interface MemberRepository extends JpaRepository{ + + Optional findByEmail(String email); +} diff --git a/src/main/java/umc/spring/service/MemberService/MemberCommandService.java b/src/main/java/umc/spring/service/MemberService/MemberCommandService.java new file mode 100644 index 0000000..05a5836 --- /dev/null +++ b/src/main/java/umc/spring/service/MemberService/MemberCommandService.java @@ -0,0 +1,11 @@ +package umc.spring.service.MemberService; + +import org.springframework.stereotype.Service; +import umc.spring.domain.Member; +import umc.spring.web.dto.MemberRequestDTO; + +@Service +public interface MemberCommandService { + + Member joinMember(MemberRequestDTO.JoinDto request); +} diff --git a/src/main/java/umc/spring/service/MemberService/MemberCommandServiceImpl.java b/src/main/java/umc/spring/service/MemberService/MemberCommandServiceImpl.java new file mode 100644 index 0000000..e749c4a --- /dev/null +++ b/src/main/java/umc/spring/service/MemberService/MemberCommandServiceImpl.java @@ -0,0 +1,50 @@ +package umc.spring.service.MemberService; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import umc.spring.apiPayload.code.status.ErrorStatus; +import umc.spring.apiPayload.exception.handler.FoodCategoryHandler; +import umc.spring.converter.MemberConverter; +import umc.spring.converter.MemberPreferConverter; +import umc.spring.domain.FoodCategory; +import umc.spring.domain.Member; +import umc.spring.domain.mapping.MemberPrefer; +import umc.spring.repository.FoodCategoryRepository; +import umc.spring.repository.MemberRepository; +import umc.spring.web.dto.MemberRequestDTO; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class MemberCommandServiceImpl implements MemberCommandService{ + + private final MemberRepository memberRepository; + + private final FoodCategoryRepository foodCategoryRepository; + + private final PasswordEncoder passwordEncoder; + + @Override + @Transactional + public Member joinMember(MemberRequestDTO.JoinDto request) { + + Member newMember = MemberConverter.toMember(request); + + newMember.encodePassword(passwordEncoder.encode(request.getPassword())); + + List foodCategoryList = request.getPreferCategory().stream() + .map(category -> { + return foodCategoryRepository.findById(category).orElseThrow(() -> new FoodCategoryHandler(ErrorStatus.FOOD_CATEGORY_NOT_FOUND)); + }).collect(Collectors.toList()); + + List memberPreferList = MemberPreferConverter.toMemberPreferList(foodCategoryList); + + memberPreferList.forEach(memberPrefer -> {memberPrefer.setMember(newMember);}); + + return memberRepository.save(newMember); + } +} diff --git a/src/main/java/umc/spring/web/controller/MemberRestController.java b/src/main/java/umc/spring/web/controller/MemberRestController.java new file mode 100644 index 0000000..dbea8dd --- /dev/null +++ b/src/main/java/umc/spring/web/controller/MemberRestController.java @@ -0,0 +1,28 @@ +package umc.spring.web.controller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import umc.spring.apiPayload.ApiResponse; +import umc.spring.converter.MemberConverter; +import umc.spring.domain.Member; +import umc.spring.service.MemberService.MemberCommandService; +import umc.spring.web.dto.MemberRequestDTO; +import umc.spring.web.dto.MemberResponseDTO; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/members") +public class MemberRestController { + + private final MemberCommandService memberCommandService; + + @PostMapping("/") + public ApiResponse join(@RequestBody @Valid MemberRequestDTO.JoinDto request){ + Member member = memberCommandService.joinMember(request); + return ApiResponse.onSuccess(MemberConverter.toJoinResultDTO(member)); + } +} diff --git a/src/main/java/umc/spring/web/controller/MemberViewController.java b/src/main/java/umc/spring/web/controller/MemberViewController.java new file mode 100644 index 0000000..150bb88 --- /dev/null +++ b/src/main/java/umc/spring/web/controller/MemberViewController.java @@ -0,0 +1,60 @@ +package umc.spring.web.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.ui.Model; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import umc.spring.service.MemberService.MemberCommandService; +import umc.spring.web.dto.MemberRequestDTO; + +@Controller +@RequiredArgsConstructor +public class MemberViewController { + + private final MemberCommandService memberCommandService; + + @GetMapping("/login") + public String loginPage() { + return "login"; + } + + // thymeleaf 사용을 위해 일부가 변경되었습니다. + // 실제로는 8주차에서 작성한 컨트롤러와 동일하게 작성하시면 됩니다!! + @PostMapping("/members/signup") + public String joinMember(@ModelAttribute("memberJoinDto") MemberRequestDTO.JoinDto request, // 협업시에는 기존 RequestBody 어노테이션을 붙여주시면 됩니다! + BindingResult bindingResult, + Model model) { + if (bindingResult.hasErrors()) { + // 뷰에 데이터 바인딩이 실패할 경우 signup 페이지를 유지합니다. + return "signup"; + } + + try { + memberCommandService.joinMember(request); + return "redirect:/login"; + } catch (Exception e) { + // 회원가입 과정에서 에러가 발생할 경우 에러 메시지를 보내고, signup 페이디를 유지합니다. + model.addAttribute("error", e.getMessage()); + return "signup"; + } + } + + @GetMapping("/signup") + public String signupPage(Model model) { + model.addAttribute("memberJoinDto", new MemberRequestDTO.JoinDto()); + return "signup"; + } + + @GetMapping("/home") + public String home() { + return "home"; + } + + @GetMapping("/admin") + public String admin() { + return "admin"; + } +} diff --git a/src/main/java/umc/spring/web/dto/MemberRequestDTO.java b/src/main/java/umc/spring/web/dto/MemberRequestDTO.java new file mode 100644 index 0000000..677c1c9 --- /dev/null +++ b/src/main/java/umc/spring/web/dto/MemberRequestDTO.java @@ -0,0 +1,41 @@ +package umc.spring.web.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; +import umc.spring.domain.enums.Role; + +import java.util.List; + +public class MemberRequestDTO { + + @Getter + @Setter + public static class JoinDto{ + @NotBlank + String name; + @NotBlank + @Email + String email; // 이메일 필드 추가 + @NotBlank + String password; // 비밀번호 필드 추가 + @NotNull + Integer gender; + @NotNull + Integer birthYear; + @NotNull + Integer birthMonth; + @NotNull + Integer birthDay; + @Size(min = 5, max = 12) + String address; + @Size(min = 5, max = 12) + String specAddress; + List preferCategory; + @NotNull + Role role; // 역할 필드 추가 + } +} diff --git a/src/main/java/umc/spring/web/dto/MemberResponseDTO.java b/src/main/java/umc/spring/web/dto/MemberResponseDTO.java new file mode 100644 index 0000000..1c8e4eb --- /dev/null +++ b/src/main/java/umc/spring/web/dto/MemberResponseDTO.java @@ -0,0 +1,20 @@ +package umc.spring.web.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +public class MemberResponseDTO { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class JoinResultDTO{ + Long memberId; + LocalDateTime createdAt; + } +} diff --git a/src/main/java/umc/spring/web/dto/classJoinDto.java b/src/main/java/umc/spring/web/dto/classJoinDto.java new file mode 100644 index 0000000..d0ea43c --- /dev/null +++ b/src/main/java/umc/spring/web/dto/classJoinDto.java @@ -0,0 +1,18 @@ +package umc.spring.web.dto; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class classJoinDto { + + String name; + Integer gender; + Integer birthYear; + Integer birthMonth; + Integer birthDay; + String address; + String specAddress; + List preferCategory; +} diff --git a/src/main/resources/Application.yml b/src/main/resources/Application.yml index be57bf4..7208437 100644 --- a/src/main/resources/Application.yml +++ b/src/main/resources/Application.yml @@ -16,4 +16,22 @@ spring: use_sql_comments: true hbm2ddl: auto: update - default_batch_fetch_size: 1000 \ No newline at end of file + default_batch_fetch_size: 1000 + security: + oauth2: + client: + registration: + kakao: + client-authentication-method: client_secret_post + client-id: { 본인 client-id } + client-secret: { 본인 client-secret} + redirect-uri: { 본인 도메인 }/login/oauth2/code/kakao + authorization-grant-type: authorization_code + scope: profile_nickname + client-name: Kakao + provider: + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index be57bf4..7208437 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -16,4 +16,22 @@ spring: use_sql_comments: true hbm2ddl: auto: update - default_batch_fetch_size: 1000 \ No newline at end of file + default_batch_fetch_size: 1000 + security: + oauth2: + client: + registration: + kakao: + client-authentication-method: client_secret_post + client-id: { 본인 client-id } + client-secret: { 본인 client-secret} + redirect-uri: { 본인 도메인 }/login/oauth2/code/kakao + authorization-grant-type: authorization_code + scope: profile_nickname + client-name: Kakao + provider: + kakao: + authorization-uri: https://kauth.kakao.com/oauth/authorize + token-uri: https://kauth.kakao.com/oauth/token + user-info-uri: https://kapi.kakao.com/v2/user/me + user-name-attribute: id \ No newline at end of file diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html new file mode 100644 index 0000000..55dbff1 --- /dev/null +++ b/src/main/resources/templates/admin.html @@ -0,0 +1,10 @@ + + + + Admin Page + + +

Admin Page

+

관리자만 접근할 수 있는 페이지입니다.

+ + \ No newline at end of file diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html new file mode 100644 index 0000000..529b72c --- /dev/null +++ b/src/main/resources/templates/home.html @@ -0,0 +1,17 @@ + + + + Home + + +

Welcome to Home Page!

+

+ + + +
+ +
+ \ No newline at end of file diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 0000000..26a3bcd --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,30 @@ + + + + Login + + +

Login

+
+
+ + +
+
+ + +
+ +
+ +

사용자 이름 또는 비밀번호가 잘못되었습니다.

+

로그아웃되었습니다.

+ + +

계정이 없나요? Sign up

+ + +카카오로 로그인 + + + \ No newline at end of file diff --git a/src/main/resources/templates/signup.html b/src/main/resources/templates/signup.html new file mode 100644 index 0000000..ff2a177 --- /dev/null +++ b/src/main/resources/templates/signup.html @@ -0,0 +1,71 @@ + + + + 회원가입 + + + +

회원가입

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + +
+
+
+ + +
+ +
+ + \ No newline at end of file