Skip to content

Commit 33980a6

Browse files
authored
[Feat] 다국어 지원 기능 추가 (#358)
* feat: User Entity내 language컬럼 추가 및 flyway 쿼리문 추가 * feat: 유저 언어 설정 API 추가 및 UserService 중복 코드 제거 * feat: College Entity내 i8n컬럼 추가 및 flyway 쿼리문 추가 * feat: Department Entity내 i8n컬럼 추가 및 flyway 쿼리문 추가 * feat: PartnershipRestaurant Entity내 i8n컬럼 추가 및 flyway 쿼리문 추가 * feat: 제휴정보 조회 시 유저의 언어 설정에 따라서 store_name 분기 처리 추가 * feat: 단과대/학과 정보 조회 시 유저의 언어 설정에 따른 분기 처리 추가 * feat: 유저 프로필 조회에 언어 값 추가 및 유저의 언어 설정 조회 API 추가 * fix: 리뷰사항 반영 * fix: UserService @component 중복 선언 제거 및 @transactional import 경로 수정 * fix: 리뷰 반영
1 parent 061ff12 commit 33980a6

21 files changed

Lines changed: 288 additions & 51 deletions

src/main/java/ssu/eatssu/domain/partnership/dto/PartnershipResponse.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.Getter;
66
import ssu.eatssu.domain.partnership.entity.PartnershipRestaurant;
77
import ssu.eatssu.domain.partnership.entity.RestaurantType;
8+
import ssu.eatssu.domain.user.entity.Language;
89

910
import java.util.List;
1011
import java.util.stream.Collectors;
@@ -19,7 +20,7 @@ public class PartnershipResponse {
1920
private RestaurantType restaurantType;
2021
private List<PartnershipInfo> partnershipInfos;
2122

22-
public static PartnershipResponse fromEntity(PartnershipRestaurant restaurant, Long userId) {
23+
public static PartnershipResponse fromEntity(PartnershipRestaurant restaurant, Long userId, Language language) {
2324
boolean isLiked = restaurant.getLikes().stream()
2425
.anyMatch(like -> like.getUser().getId().equals(userId));
2526

@@ -30,7 +31,7 @@ public static PartnershipResponse fromEntity(PartnershipRestaurant restaurant, L
3031
.collect(Collectors.toList());
3132

3233
return PartnershipResponse.builder()
33-
.storeName(restaurant.getStoreName())
34+
.storeName(restaurant.getStoreNameByLanguage(language))
3435
.longitude(restaurant.getLongitude())
3536
.latitude(restaurant.getLatitude())
3637
.restaurantType(restaurant.getRestaurantType())

src/main/java/ssu/eatssu/domain/partnership/entity/PartnershipRestaurant.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
import lombok.Getter;
1414
import lombok.NoArgsConstructor;
1515
import org.hibernate.annotations.BatchSize;
16+
import ssu.eatssu.domain.user.entity.Language;
17+
import ssu.eatssu.global.i18n.Localizable;
1618

1719
import java.util.ArrayList;
1820
import java.util.List;
1921

2022
@Entity
2123
@Getter
2224
@NoArgsConstructor(access = AccessLevel.PROTECTED)
23-
public class PartnershipRestaurant {
25+
public class PartnershipRestaurant implements Localizable {
2426
@Id
2527
@GeneratedValue(strategy = GenerationType.IDENTITY)
2628
@Column(name = "partnershipRestaurant_id")
@@ -34,12 +36,26 @@ public class PartnershipRestaurant {
3436

3537
@Column(name = "latitude", nullable = false)
3638
private Double latitude; // 위도 == y축
37-
@Column(name = "store_name", nullable = false)
38-
private String storeName;
39+
@Column(name = "store_name_ko", nullable = false)
40+
private String storeNameKo;
41+
@Column(name = "store_name_en")
42+
private String storeNameEn;
43+
@Column(name = "store_name_ja")
44+
private String storeNameJa;
45+
@Column(name = "store_name_vi")
46+
private String storeNameVi;
3947

4048
@OneToMany(mappedBy = "partnershipRestaurant")
4149
@BatchSize(size = 20)
4250
private List<PartnershipLike> likes = new ArrayList<>();
4351
@OneToMany(mappedBy = "partnershipRestaurant", cascade = CascadeType.ALL, orphanRemoval = true)
4452
private List<Partnership> partnerships = new ArrayList<>();
53+
54+
public String getStoreName() {
55+
return storeNameKo;
56+
}
57+
58+
public String getStoreNameByLanguage(Language language) {
59+
return getLocalizedValue(language, storeNameKo, storeNameEn, storeNameJa, storeNameVi);
60+
}
4561
}

src/main/java/ssu/eatssu/domain/partnership/service/PartnershipService.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import ssu.eatssu.domain.user.department.entity.Department;
1919
import ssu.eatssu.domain.user.department.persistence.CollegeRepository;
2020
import ssu.eatssu.domain.user.department.persistence.DepartmentRepository;
21+
import ssu.eatssu.domain.user.entity.Language;
2122
import ssu.eatssu.domain.user.entity.User;
2223
import ssu.eatssu.domain.user.repository.UserRepository;
2324
import ssu.eatssu.global.handler.response.BaseException;
@@ -52,19 +53,22 @@ public void createPartnership(CreatePartnershipRequest request) {
5253
NOT_FOUND_PARTNERSHIP_RESTAURANT));
5354
Partnership partnership = request.toPartnershipEntity(partnershipRestaurant);
5455

55-
College college = collegeRepository.findByName(request.getCollege())
56+
College college = collegeRepository.findByNameKo(request.getCollege())
5657
.orElseThrow(() -> new BaseException(NOT_FOUND_COLLEGE));
5758
partnership.setPartnershipCollege(college);
58-
Department department = departmentRepository.findByName(request.getDepartment())
59+
Department department = departmentRepository.findByNameKo(request.getDepartment())
5960
.orElseThrow(() -> new BaseException(NOT_FOUND_DEPARTMENT));
6061
partnership.setPartnershipDepartment(department);
6162
partnershipRepository.save(partnership);
6263
}
6364

6465
public List<PartnershipResponse> getAllPartnerships(CustomUserDetails customUserDetails) {
66+
Language language = findUserByUserDetails(customUserDetails).getLanguage();
67+
6568
return partnerShipRestaurantRepository.findAllWithDetails().stream()
6669
.map(restaurant -> PartnershipResponse.fromEntity(restaurant,
67-
customUserDetails.getId()))
70+
customUserDetails.getId(),
71+
language))
6872
.collect(Collectors.toList());
6973
}
7074

@@ -100,8 +104,7 @@ public void togglePartnershipLike(Long partnershipId, CustomUserDetails userDeta
100104
}
101105

102106
public List<PartnershipResponse> getUserLikedPartnerships(CustomUserDetails customUserDetails) {
103-
User user = userRepository.findById(customUserDetails.getId())
104-
.orElseThrow(() -> new BaseException(NOT_FOUND_USER));
107+
User user = findUserByUserDetails(customUserDetails);
105108

106109
List<PartnershipLike> likes = partnershipLikeRepository.findAllByUserWithDetails(user);
107110

@@ -111,14 +114,14 @@ public List<PartnershipResponse> getUserLikedPartnerships(CustomUserDetails cust
111114
return restaurant.getPartnerships()
112115
.stream()
113116
.map(partnership -> PartnershipResponse.fromEntity(restaurant,
114-
customUserDetails.getId()));
117+
customUserDetails.getId(),
118+
user.getLanguage()));
115119
}).collect(Collectors.toList());
116120
}
117121

118122

119123
public List<PartnershipResponse> getUserDepartmentPartnerships(CustomUserDetails customUserDetails) {
120-
User user = userRepository.findById(customUserDetails.getId())
121-
.orElseThrow(() -> new BaseException(NOT_FOUND_USER));
124+
User user = findUserByUserDetails(customUserDetails);
122125

123126
Department department = user.getDepartment();
124127
if (department == null) {
@@ -130,7 +133,13 @@ public List<PartnershipResponse> getUserDepartmentPartnerships(CustomUserDetails
130133
.findRestaurantsWithMyPartnerships(college, department)
131134
.stream()
132135
.map(partnershipRestaurant -> PartnershipResponse.fromEntity(partnershipRestaurant,
133-
customUserDetails.getId()))
136+
customUserDetails.getId(),
137+
user.getLanguage()))
134138
.collect(Collectors.toList());
135139
}
140+
141+
private User findUserByUserDetails(CustomUserDetails userDetails) {
142+
return userRepository.findById(userDetails.getId())
143+
.orElseThrow(() -> new BaseException(NOT_FOUND_USER));
144+
}
136145
}

src/main/java/ssu/eatssu/domain/user/department/entity/College.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@
1111
import lombok.Getter;
1212
import lombok.NoArgsConstructor;
1313
import ssu.eatssu.domain.partnership.entity.Partnership;
14+
import ssu.eatssu.domain.user.entity.Language;
15+
import ssu.eatssu.global.i18n.Localizable;
1416

1517
import java.util.ArrayList;
1618
import java.util.List;
1719

1820
@Entity
1921
@Getter
2022
@NoArgsConstructor(access = AccessLevel.PROTECTED)
21-
public class College {
23+
public class College implements Localizable {
2224
@OneToMany(mappedBy = "college", cascade = CascadeType.ALL, orphanRemoval = true)
2325
private final List<Department> departments = new ArrayList<>();
2426
@OneToMany(mappedBy = "partnershipCollege", cascade = CascadeType.ALL, orphanRemoval = true)
@@ -27,10 +29,24 @@ public class College {
2729
@GeneratedValue(strategy = GenerationType.IDENTITY)
2830
@Column(name = "college_id")
2931
private Long id;
30-
@Column(nullable = false, unique = true)
31-
private String name;
32+
@Column(name = "name_ko", nullable = false, unique = true)
33+
private String nameKo;
34+
@Column(name = "name_en")
35+
private String nameEn;
36+
@Column(name = "name_ja")
37+
private String nameJa;
38+
@Column(name = "name_vi")
39+
private String nameVi;
3240

3341
public College(String name) {
34-
this.name = name;
42+
this.nameKo = name;
43+
}
44+
45+
public String getName() {
46+
return nameKo;
47+
}
48+
49+
public String getNameByLanguage(Language language) {
50+
return getLocalizedValue(language, nameKo, nameEn, nameJa, nameVi);
3551
}
3652
}

src/main/java/ssu/eatssu/domain/user/department/entity/Department.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,43 @@
1414
import lombok.Getter;
1515
import lombok.NoArgsConstructor;
1616
import ssu.eatssu.domain.partnership.entity.Partnership;
17+
import ssu.eatssu.domain.user.entity.Language;
18+
import ssu.eatssu.global.i18n.Localizable;
1719

1820
import java.util.ArrayList;
1921
import java.util.List;
2022

2123
@Entity
2224
@Getter
2325
@NoArgsConstructor(access = AccessLevel.PROTECTED)
24-
public class Department {
26+
public class Department implements Localizable {
2527
@OneToMany(mappedBy = "partnershipDepartment", cascade = CascadeType.ALL, orphanRemoval = true)
2628
private final List<Partnership> partnerships = new ArrayList<>();
2729
@Id
2830
@GeneratedValue(strategy = GenerationType.IDENTITY)
2931
@Column(name = "department_id")
3032
private Long id;
31-
@Column(nullable = false)
32-
private String name;
33+
@Column(name = "name_ko", nullable = false)
34+
private String nameKo;
35+
@Column(name = "name_en")
36+
private String nameEn;
37+
@Column(name = "name_ja")
38+
private String nameJa;
39+
@Column(name = "name_vi")
40+
private String nameVi;
3341
@ManyToOne(fetch = FetchType.LAZY)
3442
@JoinColumn(name = "college_id")
3543
private College college;
3644

3745
public Department(String name) {
38-
this.name = name;
46+
this.nameKo = name;
47+
}
48+
49+
public String getName() {
50+
return nameKo;
51+
}
52+
53+
public String getNameByLanguage(Language language) {
54+
return getLocalizedValue(language, nameKo, nameEn, nameJa, nameVi);
3955
}
4056
}

src/main/java/ssu/eatssu/domain/user/department/persistence/CollegeRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
import java.util.Optional;
77

88
public interface CollegeRepository extends JpaRepository<College, Long> {
9-
Optional<College> findByName(String name);
9+
Optional<College> findByNameKo(String nameKo);
1010
}

src/main/java/ssu/eatssu/domain/user/department/persistence/DepartmentRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.util.Optional;
99

1010
public interface DepartmentRepository extends JpaRepository<Department, Long> {
11-
Optional<Department> findByName(String name);
11+
Optional<Department> findByNameKo(String nameKo);
1212

1313
List<Department> findByCollege(College college);
1414
}

src/main/java/ssu/eatssu/domain/user/dto/DepartmentResponse.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@
33
import lombok.Builder;
44
import ssu.eatssu.domain.user.department.entity.College;
55
import ssu.eatssu.domain.user.department.entity.Department;
6+
import ssu.eatssu.domain.user.entity.Language;
67

78
@Builder
89
public record DepartmentResponse(
910
Long departmentId, String departmentName, Long collegeId, String collegeName
1011
) {
1112
public static DepartmentResponse from(Department department) {
13+
return from(department, Language.KO);
14+
}
15+
16+
public static DepartmentResponse from(Department department, Language language) {
1217
if (department == null) {
1318
return new DepartmentResponse(null, null, null, null);
1419
}
1520
final College college = department.getCollege();
1621
return DepartmentResponse.builder()
1722
.departmentId(department.getId())
18-
.departmentName(department.getName())
23+
.departmentName(department.getNameByLanguage(language))
1924
.collegeId(college != null ? college.getId() : null)
20-
.collegeName(college != null ? college.getName() : null)
25+
.collegeName(college != null ? college.getNameByLanguage(language) : null)
2126
.build();
2227
}
2328
}
24-
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package ssu.eatssu.domain.user.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import ssu.eatssu.domain.user.entity.Language;
5+
import ssu.eatssu.domain.user.entity.User;
6+
7+
@Schema(title = "언어 설정 조회")
8+
public record LanguageResponse(
9+
@Schema(description = "언어 설정", example = "KO")
10+
Language language) {
11+
12+
public static LanguageResponse from(User user) {
13+
return new LanguageResponse(user.getLanguage());
14+
}
15+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package ssu.eatssu.domain.user.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.NotNull;
5+
import ssu.eatssu.domain.user.entity.Language;
6+
7+
@Schema(title = "언어 설정 수정")
8+
public record LanguageUpdateRequest(
9+
@NotNull(message = "언어 설정을 입력해주세요.")
10+
@Schema(description = "언어 설정", example = "EN", allowableValues = {"KO", "EN", "JA", "VI"})
11+
Language language) {
12+
}

0 commit comments

Comments
 (0)