├── .github ├── ISSUE_TEMPLATE │ └── ✅-feature.md └── workflows │ └── sonarcloud-analyze.yml ├── .gitignore ├── Dockerfile ├── HELP.md ├── README.md ├── build.gradle ├── fkream 인프라 구조.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main ├── java │ └── com │ │ └── flab │ │ └── fkream │ │ ├── AutoComplete │ │ ├── AutoCompleteController.java │ │ ├── AutoCompleteService.java │ │ ├── AutoCompletedItemDto.java │ │ ├── Trie.java │ │ └── TrieNode.java │ │ ├── FkreamApplication.java │ │ ├── address │ │ ├── Address.java │ │ ├── AddressController.java │ │ ├── AddressRepository.java │ │ └── AddressService.java │ │ ├── aop │ │ ├── AuthCheckAspect.java │ │ ├── LoginCheck.java │ │ ├── Paging.java │ │ └── PagingAspect.java │ │ ├── brand │ │ ├── Brand.java │ │ ├── BrandController.java │ │ └── BrandService.java │ │ ├── config │ │ ├── CacheConfig.java │ │ ├── RedisCacheConfig.java │ │ ├── RedisClusterConfigurationProperties.java │ │ ├── RedisSessionConfig.java │ │ └── RedissonConfig.java │ │ ├── constants │ │ └── Constants.java │ │ ├── deal │ │ ├── BiddingPriceDto.java │ │ ├── CompleteDealPriceDto.java │ │ ├── Deal.java │ │ ├── DealController.java │ │ ├── DealHistoryCountDto.java │ │ ├── DealHistoryDto.java │ │ ├── DealPeriod.java │ │ ├── DealService.java │ │ ├── DealStatus.java │ │ ├── DealType.java │ │ └── MarketPriceDto.java │ │ ├── error │ │ ├── ErrorController.java │ │ ├── ErrorMsg.java │ │ ├── ValidationErrorMsg.java │ │ └── exception │ │ │ ├── DuplicatedEmailException.java │ │ │ ├── ForbiddenException.java │ │ │ ├── GenerateAddressKeyException.java │ │ │ ├── InvalidShardKeyException.java │ │ │ ├── LoginFailureException.java │ │ │ ├── LoginRequiredException.java │ │ │ ├── NoCardPasswordException.java │ │ │ ├── NoDataFoundException.java │ │ │ ├── NoMatchDealStatusException.java │ │ │ ├── NoMatchDealTypeException.java │ │ │ ├── NoRequestHigherPriceThenImmediatePurchaseException.java │ │ │ ├── NoRequestLowerPriceThenImmediateSaleException.java │ │ │ ├── NotOwnedDataException.java │ │ │ ├── ShardingStrategyNotFoundException.java │ │ │ └── SignUpFailureException.java │ │ ├── interestItemCount │ │ ├── InterestItemCount.java │ │ ├── InterestItemCountController.java │ │ ├── InterestItemCountRepository.java │ │ └── InterestItemCountService.java │ │ ├── interestedItem │ │ ├── InterestedItem.java │ │ ├── InterestedItemController.java │ │ └── InterestedItemService.java │ │ ├── item │ │ ├── Item.java │ │ ├── ItemController.java │ │ ├── ItemGender.java │ │ └── ItemService.java │ │ ├── itemCategory │ │ ├── ItemCategory.java │ │ ├── ItemCategoryController.java │ │ ├── ItemCategoryDto.java │ │ └── ItemCategoryService.java │ │ ├── itemImg │ │ ├── ItemImg.java │ │ ├── ItemImgController.java │ │ └── ItemImgService.java │ │ ├── itemSizePrice │ │ ├── ItemSizePrice.java │ │ ├── ItemSizePriceController.java │ │ └── ItemSizePriceService.java │ │ ├── kafka │ │ ├── KafkaConsumeConfig.java │ │ ├── KafkaMessageSender.java │ │ ├── KafkaProducerConfig.java │ │ ├── KafkaSearchListener.java │ │ ├── KafkaTopic.java │ │ └── KafkaTopicConfig.java │ │ ├── listing │ │ ├── ItemGenerateStrategy │ │ │ ├── ItemsBelowReleasedPriceStrategy.java │ │ │ ├── MostPopularStrategy.java │ │ │ ├── PopularLuxuryItemsStrategy.java │ │ │ ├── PopularSneakersStrategy.java │ │ │ ├── RecommendedItemForMenStrategy.java │ │ │ └── RecommendedItemForWomenStrategy.java │ │ ├── ItemGenerationStrategy.java │ │ ├── ItemGenerationStrategyFactory.java │ │ ├── ListingController.java │ │ ├── ListingCriteria.java │ │ └── ListingService.java │ │ ├── login │ │ ├── LoginController.java │ │ └── LoginForm.java │ │ ├── manager │ │ ├── Manager.java │ │ ├── ManagerController.java │ │ └── ManagerService.java │ │ ├── mapper │ │ ├── AddressMapper.java │ │ ├── BrandMapper.java │ │ ├── DealMapper.java │ │ ├── InterestedItemMapper.java │ │ ├── ItemCategoryMapper.java │ │ ├── ItemImgMapper.java │ │ ├── ItemMapper.java │ │ ├── ItemSizePriceMapper.java │ │ ├── ListingMapper.java │ │ ├── ManagerMapper.java │ │ ├── MyItemMapper.java │ │ ├── NotificationMapper.java │ │ ├── PaymentCardMapper.java │ │ ├── SalesAccountMapper.java │ │ ├── SearchMapper.java │ │ └── UserMapper.java │ │ ├── myItems │ │ ├── MyItem.java │ │ ├── MyItemController.java │ │ └── MyItemService.java │ │ ├── notification │ │ ├── Notification.java │ │ ├── NotificationController.java │ │ ├── NotificationService.java │ │ └── NotificationType.java │ │ ├── paymentCard │ │ ├── PaymentCard.java │ │ ├── PaymentCardController.java │ │ └── PaymentCardService.java │ │ ├── redis │ │ └── RedisService.java │ │ ├── resolver │ │ ├── QueryStringArgResolver.java │ │ └── QueryStringArgumentResolver.java │ │ ├── salesAccount │ │ ├── SalesAccount.java │ │ ├── SalesAccountController.java │ │ └── SalesAccountService.java │ │ ├── search │ │ ├── SearchCriteria.java │ │ ├── SearchService.java │ │ ├── SortCriteria.java │ │ ├── dbSearch │ │ │ ├── SearchController.java │ │ │ ├── SearchItemDto.java │ │ │ └── SearchServiceImpl.java │ │ └── elasticsearch │ │ │ ├── AbstractElasticsearchConfiguration.java │ │ │ ├── ElasticSearchConfig.java │ │ │ ├── ElasticSearchCriteria.java │ │ │ ├── ItemDocument.java │ │ │ ├── ItemDocumentsDto.java │ │ │ ├── ItemSearchController.java │ │ │ ├── ItemSearchRepository.java │ │ │ ├── ItemSearchService.java │ │ │ ├── PremiumRateBySize.java │ │ │ ├── SearchDocument.java │ │ │ ├── SearchRankingRepository.java │ │ │ └── SearchRankingService.java │ │ ├── sharding │ │ ├── AddressShardingConfig.java │ │ ├── AllShardQuery.java │ │ ├── DataSourceRouter.java │ │ ├── MapperShardingAspect.java │ │ ├── Sharding.java │ │ ├── ShardingConfig.java │ │ ├── ShardingDataSourceConfig.java │ │ ├── ShardingDataSourceProperty.java │ │ ├── ShardingProperty.java │ │ ├── ShardingStrategy.java │ │ ├── ShardingTarget.java │ │ └── UserHolder.java │ │ ├── user │ │ ├── User.java │ │ ├── UserController.java │ │ └── UserService.java │ │ └── utils │ │ ├── HttpRequestUtils.java │ │ ├── SHA256Util.java │ │ └── SessionUtil.java └── resources │ ├── application-test.yml │ ├── application.yml │ ├── db_sql │ ├── data.sql │ ├── schema.sql │ └── testSchema.sql │ ├── elastic │ ├── item-mapping.json │ └── item-setting.json │ ├── log4jdbc.log4j2.properties │ └── mybatis │ └── mapper │ ├── AddressMapper.xml │ ├── BrandMapper.xml │ ├── DealMapper.xml │ ├── InterestedItem.xml │ ├── ItemCategoryMapper.xml │ ├── ItemImgMapper.xml │ ├── ItemMapper.xml │ ├── ItemSizePriceMapper.xml │ ├── ListingMapper.xml │ ├── ManagerMapper.xml │ ├── MyItemMapper.xml │ ├── NotifiactionMapper.xml │ ├── PaymentCardMapper.xml │ ├── SalesAccountMapper.xml │ ├── SearchMapper.xml │ └── UsersMapper.xml └── test ├── http └── http_request.http └── java └── com └── flab └── fkream ├── FkreamApplicationTests.java ├── Integration └── DealTest.java ├── address ├── AddressControllerTest.java ├── AddressMapperTest.java └── AddressServiceTest.java ├── brand ├── BrandControllerTest.java ├── BrandMapperTest.java └── BrandServiceTest.java ├── deal ├── DealControllerTest.java ├── DealMapperTest.java └── DealServiceTest.java ├── interestedItem ├── InterestedItemControllerTest.java ├── InterestedItemMapperTest.java └── InterestedItemServiceTest.java ├── item ├── ItemControllerTest.java ├── ItemMapperTest.java └── ItemServiceTest.java ├── itemCategory ├── ItemCategoryControllerTest.java ├── ItemCategoryMapperTest.java └── ItemCategoryServiceTest.java ├── itemImg ├── ItemImgControllerTest.java ├── ItemImgMapperTest.java └── ItemImgServiceTest.java ├── itemSizePrice ├── ItemSizePriceControllerTest.java ├── ItemSizePriceMapperTest.java └── ItemSizePriceServiceTest.java ├── listing ├── ListingControllerTest.java ├── ListingMapperTest.java └── ListingServiceTest.java ├── login └── LoginControllerTest.java ├── myItems ├── MyItemControllerTest.java ├── MyItemMapperTest.java └── MyItemServiceTest.java ├── paymentCard ├── PaymentCardControllerTest.java ├── PaymentCardMapperTest.java └── PaymentCardServiceTest.java ├── redis └── RedisServiceTest.java ├── salesAccount ├── SalesAccountControllerTest.java ├── SalesAccountMapperTest.java └── SalesAccountServiceTest.java ├── search ├── SearchControllerTest.java ├── SearchMapperTest.java ├── SearchServiceImplTest.java └── TrieTest.java ├── sharding └── ShardingTest.java └── user ├── UserControllerTest.java ├── UserMapperTest.java └── UserServiceTest.java /.github/ISSUE_TEMPLATE/✅-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "✅ Feature" 3 | about: Feature 작업 사항을 입력해주세요. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description 11 | 설명을 작성해주세요. 12 | 13 | ## Todo 14 | - [ ] todo 15 | - [ ] todo 16 | 17 | ## ETC 18 | 기타사항 19 | -------------------------------------------------------------------------------- /.github/workflows/sonarcloud-analyze.yml: -------------------------------------------------------------------------------- 1 | name: F-Lab SonarCloud Code Analyze 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened] 6 | workflow_dispatch: 7 | 8 | env: 9 | CACHED_DEPENDENCIES_PATHS: '**/node_modules' 10 | 11 | jobs: 12 | CodeAnalyze: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Set SonarCloud Project Key 21 | run: | 22 | REPO_NAME=$(echo $GITHUB_REPOSITORY | cut -d '/' -f 2) 23 | ORG_NAME=$(echo $GITHUB_REPOSITORY | cut -d '/' -f 1) 24 | SONAR_PROJECT_KEY="${ORG_NAME}_${REPO_NAME}" 25 | echo "SONAR_PROJECT_KEY=$SONAR_PROJECT_KEY" >> $GITHUB_ENV 26 | 27 | - name: Set up JDK 28 | uses: actions/setup-java@v2 29 | with: 30 | java-version: '19' 31 | distribution: 'adopt' 32 | 33 | - name: Create Sonar Gradle File 34 | run: | 35 | insert_string="plugins { id 'org.sonarqube' version '4.4.1.3373' }" 36 | if [ -f "build.gradle" ]; then 37 | echo "$insert_string" > temp.gradle 38 | cat build.gradle >> temp.gradle 39 | echo "" >> temp.gradle 40 | echo "sonarqube {" >> temp.gradle 41 | echo " properties {" >> temp.gradle 42 | echo " property 'sonar.java.binaries', '**'" >> temp.gradle 43 | echo " }" >> temp.gradle 44 | echo "}" >> temp.gradle 45 | mv temp.gradle build.gradle 46 | else 47 | echo "$insert_string" > build.gradle 48 | echo "" >> build.gradle 49 | echo "sonarqube {" >> build.gradle 50 | echo " properties {" >> build.gradle 51 | echo " property 'sonar.java.binaries', '**'" >> build.gradle 52 | echo " }" >> build.gradle 53 | echo "}" >> build.gradle 54 | fi 55 | 56 | 57 | - name: Analyze 58 | run: ./gradlew sonar -Dsonar.projectKey=${{ env.SONAR_PROJECT_KEY }} -Dsonar.organization=f-lab-edu-1 -Dsonar.host.url=https://sonarcloud.io -Dsonar.token=${{ secrets.SECRET_SONARQUBE }} -Dsonar.gradle.skipCompile=true 59 | env: 60 | SONAR_TOKEN: ${{ secrets.SECRET_SONARQUBE }} 61 | 62 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:11-jdk 2 | LABEL maintainer="email" 3 | ARG JAR_FILE=build/libs/fkream-0.0.1-SNAPSHOT.jar 4 | ADD ${JAR_FILE} docker-springboot.jar 5 | #ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/docker-springboot.jar"] 6 | 7 | ENTRYPOINT ["java","-jar",\ 8 | "-javaagent:./pinpoint/pinpoint-bootstrap-2.2.2.jar",\ 9 | "-Dpinpoint.applicationName=fkream",\ 10 | "-Dpinpoint.config=./pinpoint/pinpoint-root.config"\ 11 | ,"docker-springboot.jar"] -------------------------------------------------------------------------------- /HELP.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Gradle documentation](https://docs.gradle.org) 7 | * [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.7.9/gradle-plugin/reference/html/) 8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.7.9/gradle-plugin/reference/html/#build-image) 9 | * [Spring Web](https://docs.spring.io/spring-boot/docs/2.7.9/reference/htmlsingle/#web) 10 | * [Validation](https://docs.spring.io/spring-boot/docs/2.7.9/reference/htmlsingle/#io.validation) 11 | * [MyBatis Framework](https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/) 12 | 13 | ### Guides 14 | The following guides illustrate how to use some features concretely: 15 | 16 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) 17 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) 18 | * [Building REST services with Spring](https://spring.io/guides/tutorials/rest/) 19 | * [Validation](https://spring.io/guides/gs/validating-form-input/) 20 | * [MyBatis Quick Start](https://github.com/mybatis/spring-boot-starter/wiki/Quick-Start) 21 | * [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/) 22 | 23 | ### Additional Links 24 | These additional references should also help you: 25 | 26 | * [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle) 27 | 28 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java' 3 | id 'org.springframework.boot' version '2.7.9' 4 | id 'io.spring.dependency-management' version '1.0.15.RELEASE' 5 | } 6 | 7 | group = 'com.flab' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '11' 10 | 11 | configurations { 12 | compileOnly { 13 | extendsFrom annotationProcessor 14 | } 15 | } 16 | 17 | repositories { 18 | mavenCentral() 19 | } 20 | 21 | dependencies { 22 | implementation 'org.springframework.boot:spring-boot-starter-parent:2.5.3' 23 | implementation 'org.springframework.boot:spring-boot-starter-validation' 24 | implementation 'org.springframework.boot:spring-boot-starter-web' 25 | implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.0' 26 | implementation 'org.springframework.boot:spring-boot-starter-aop:2.7.8' 27 | implementation 'org.springframework.boot:spring-boot-starter-cache' 28 | implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16' 29 | implementation 'com.oracle.database.jdbc:ojdbc11-production:21.9.0.0' 30 | implementation 'org.springframework.session:spring-session-data-redis' 31 | implementation 'org.springframework.boot:spring-boot-starter-data-redis' 32 | implementation ("org.springframework.boot:spring-boot-starter-actuator") 33 | implementation 'com.github.pagehelper:pagehelper-spring-boot-starter:1.4.2' 34 | implementation 'com.fasterxml.jackson.core:jackson-databind' 35 | implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310' 36 | // redisson 37 | implementation 'org.redisson:redisson-spring-boot-starter:3.17.4' 38 | implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' 39 | implementation 'org.springframework.boot:spring-boot-starter-parent' 40 | 41 | implementation 'org.springframework.kafka:spring-kafka' 42 | testImplementation 'org.springframework.kafka:spring-kafka-test' 43 | 44 | // elasticsearch 45 | implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' 46 | compileOnly 'org.springframework.boot:spring-boot-configuration-processor:2.7.12' 47 | compileOnly 'org.projectlombok:lombok' 48 | runtimeOnly 'com.h2database:h2' 49 | runtimeOnly 'com.mysql:mysql-connector-j' 50 | annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:2.7.12' 51 | annotationProcessor 'org.projectlombok:lombok' 52 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 53 | testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.3.0' 54 | testImplementation 'org.mockito:mockito-inline' 55 | } 56 | 57 | tasks.named('test') { 58 | useJUnitPlatform() 59 | } 60 | -------------------------------------------------------------------------------- /fkream 인프라 구조.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-lab-edu/FKREAM/3927c1f7a532da0e3d0ed16f183bb3ee73e19004/fkream 인프라 구조.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f-lab-edu/FKREAM/3927c1f7a532da0e3d0ed16f183bb3ee73e19004/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'fkream' 2 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/AutoComplete/AutoCompleteController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.AutoComplete; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.flab.fkream.item.Item; 5 | import com.flab.fkream.item.ItemService; 6 | import java.util.List; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/auto-complete") 15 | @RequiredArgsConstructor 16 | public class AutoCompleteController { 17 | 18 | private final ItemService autoCompleteService; 19 | 20 | @GetMapping("/auto-complete") 21 | public List searchAutoCompletedItem(@RequestParam String context) 22 | throws JsonProcessingException { 23 | return autoCompleteService.autoComplete(context); 24 | } 25 | 26 | @GetMapping("/init") 27 | public void init() throws JsonProcessingException { 28 | autoCompleteService.initTrie(); 29 | } 30 | 31 | @GetMapping("/test") 32 | public Item test() { 33 | return autoCompleteService.findOne(2L); 34 | } 35 | 36 | @GetMapping("/autoDB") 37 | public List searchItem(@RequestParam String context) { 38 | 39 | return autoCompleteService.autoCompleteByDB(context); 40 | } 41 | 42 | @GetMapping("/autoES") 43 | public List searchItemES(@RequestParam String context) { 44 | return autoCompleteService.autoCompleteByES(context); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/AutoComplete/AutoCompletedItemDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.AutoComplete; 2 | 3 | import com.flab.fkream.item.Item; 4 | import com.flab.fkream.itemImg.ItemImg; 5 | import java.io.Serializable; 6 | import java.util.ArrayList; 7 | import java.util.Comparator; 8 | import java.util.List; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Builder; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | public class AutoCompletedItemDto implements Comparable { 19 | 20 | private Long itemId; 21 | 22 | private String itemName; 23 | 24 | private int count; 25 | 26 | private Long itemImgId; 27 | 28 | private String imgName; 29 | 30 | private String imgUrl; 31 | 32 | public static AutoCompletedItemDto of(Item item) { 33 | return AutoCompletedItemDto.builder().itemId(item.getId()).itemName(item.getItemName()).build(); 34 | } 35 | 36 | public static List of(List items) { 37 | return new ArrayList<>(); 38 | } 39 | 40 | @Override 41 | public int compareTo(AutoCompletedItemDto o) { 42 | return Integer.compare(this.count, o.getCount()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/AutoComplete/Trie.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.AutoComplete; 2 | 3 | import com.flab.fkream.item.Item; 4 | import java.io.Serializable; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Map; 8 | import lombok.Getter; 9 | import lombok.RequiredArgsConstructor; 10 | import lombok.Setter; 11 | import org.springframework.stereotype.Component; 12 | 13 | @Getter 14 | @Setter 15 | public class Trie { 16 | 17 | private TrieNode root = new TrieNode(); 18 | 19 | public void insert(Item item) { 20 | String word = item.getItemName(); 21 | TrieNode node = root; 22 | for (char c : word.toCharArray()) { 23 | c = Character.toLowerCase(c); 24 | if (!node.getChildren().containsKey(c)) { 25 | TrieNode trieNode = new TrieNode(); 26 | node.getChildren().put(c, trieNode); 27 | } 28 | node = node.getChildren().get(c); 29 | } 30 | node.setEnd(true); 31 | if (node.isEnd()) { 32 | node.setItem(item); 33 | } 34 | } 35 | 36 | public List search(String word) { 37 | List results = new ArrayList<>(); 38 | TrieNode node = root; 39 | for (char c : word.toCharArray()) { 40 | c = Character.toLowerCase(c); 41 | if (!node.getChildren().containsKey(c)) { 42 | return results; 43 | } 44 | node = node.getChildren().get(c); 45 | } 46 | findAllWords(node, word, results); 47 | return results; 48 | } 49 | 50 | private void findAllWords(TrieNode node, String prefix, List result) { 51 | if (node.isEnd()) { 52 | result.add(node.getItem()); 53 | } 54 | for (Map.Entry entry : node.getChildren().entrySet()) { 55 | char ch = entry.getKey(); 56 | TrieNode child = entry.getValue(); 57 | findAllWords(child, prefix + ch, result); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/AutoComplete/TrieNode.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.AutoComplete; 2 | 3 | import com.flab.fkream.item.Item; 4 | import java.io.Serializable; 5 | import java.util.ArrayDeque; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Queue; 10 | import java.util.TreeMap; 11 | import lombok.Getter; 12 | import lombok.Setter; 13 | 14 | @Getter 15 | @Setter 16 | public class TrieNode { 17 | 18 | private boolean end; 19 | private Item item; 20 | private Map children = new TreeMap<>(); 21 | 22 | 23 | TrieNode() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/FkreamApplication.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.context.properties.ConfigurationPropertiesScan; 7 | import org.springframework.cache.annotation.EnableCaching; 8 | import org.springframework.context.annotation.EnableAspectJAutoProxy; 9 | import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; 10 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 11 | 12 | @SpringBootApplication 13 | @EnableAspectJAutoProxy 14 | @EnableCaching 15 | @EnableMongoRepositories 16 | @ConfigurationPropertiesScan(value = "com.flab.fkream.sharding") 17 | @Slf4j 18 | public class FkreamApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(FkreamApplication.class, args); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/address/Address.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.address; 2 | 3 | import javax.validation.constraints.NotNull; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.Getter; 8 | import lombok.NoArgsConstructor; 9 | import lombok.Setter; 10 | import lombok.ToString; 11 | 12 | import java.time.LocalDateTime; 13 | 14 | @Getter 15 | @Builder 16 | @EqualsAndHashCode(of = "id") 17 | @ToString 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class Address { 21 | 22 | @Setter 23 | private Long id; 24 | @NotNull 25 | private Long userId; 26 | @NotNull 27 | private String name; 28 | @NotNull 29 | private String phoneNumber; 30 | @NotNull 31 | private String zipcode; 32 | @NotNull 33 | private String detail1; 34 | @NotNull 35 | private String detail2; 36 | private boolean defaultAddress; 37 | private LocalDateTime createdAt; 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/address/AddressController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.address; 2 | 3 | 4 | import com.flab.fkream.utils.SessionUtil; 5 | import com.github.pagehelper.PageHelper; 6 | import com.github.pagehelper.PageInfo; 7 | import javax.validation.Valid; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.web.bind.annotation.*; 10 | 11 | @RestController 12 | @RequestMapping("/address") 13 | @RequiredArgsConstructor 14 | public class AddressController { 15 | 16 | private final AddressService addressService; 17 | 18 | @PostMapping("") 19 | public void addAddress(@Valid @RequestBody Address address) { 20 | addressService.addAddress(address); 21 | } 22 | 23 | @GetMapping("/{id}") 24 | public Address findById(@PathVariable Long id) { 25 | return addressService.findById(id); 26 | } 27 | 28 | 29 | @GetMapping() 30 | public PageInfo
findOneByUserID(@RequestParam int pageNum, 31 | @RequestParam(defaultValue = "10") int pageSize) { 32 | Long userId = SessionUtil.getLoginUserId(); 33 | PageHelper.startPage(pageNum, pageSize); 34 | return PageInfo.of(addressService.findByUserId(userId)); 35 | } 36 | 37 | @PatchMapping("/{id}") 38 | public void update(@Valid @RequestBody Address address) { 39 | addressService.update(address); 40 | } 41 | 42 | @DeleteMapping("/{id}") 43 | public void delete(@PathVariable Long id) { 44 | addressService.delete(id); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/address/AddressRepository.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.address; 2 | 3 | 4 | import com.flab.fkream.mapper.AddressMapper; 5 | import com.flab.fkream.sharding.AllShardQuery; 6 | import com.flab.fkream.sharding.Sharding; 7 | import com.flab.fkream.sharding.ShardingTarget; 8 | import java.util.List; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.stereotype.Component; 11 | 12 | /** 13 | * @Sharding 어노테이션을 이용하여 첫번째 파라미터를 샤딩 키로 사용 하지만, mybatis는 첫번째 파라미터에 id 값을 넣을 객체가 있어야 한다. 따라서, 14 | * Repository 클래스를 만들어, Repository 클래스의 메소드는 id값이 첫번째 파라미터로, Mapper 클래스에는 첫번째 파라미터가 객체를 되도록 하였다. 15 | */ 16 | 17 | @Component 18 | @RequiredArgsConstructor 19 | public class AddressRepository { 20 | 21 | private final AddressMapper addressMapper; 22 | 23 | 24 | @Sharding(target = ShardingTarget.ADDRESS) 25 | public void addAddress(Long id, Address address) { 26 | addressMapper.save(address); 27 | } 28 | 29 | @Sharding(target = ShardingTarget.ADDRESS) 30 | public Address findOne(Long id) { 31 | return addressMapper.findOne(id); 32 | } 33 | 34 | @AllShardQuery 35 | public List
findByUserId(Long userId) { 36 | return addressMapper.findByUserId(userId); 37 | } 38 | 39 | @Sharding(target = ShardingTarget.ADDRESS) 40 | public void update(Long id, Address addressInfo) { 41 | addressMapper.update(addressInfo); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/address/AddressService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.address; 2 | 3 | import com.flab.fkream.mapper.AddressMapper; 4 | import com.flab.fkream.redis.RedisService; 5 | import java.util.List; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.log4j.Log4j2; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | @Log4j2 12 | @RequiredArgsConstructor 13 | public class AddressService { 14 | 15 | private final AddressMapper addressMapper; 16 | private final RedisService redisService; 17 | private final AddressRepository addressRepository; 18 | 19 | 20 | public void addAddress(Address address) { 21 | Long addressId = redisService.getAddressId(); 22 | address.setId(addressId); 23 | addressRepository.addAddress(addressId, address); 24 | } 25 | 26 | public Address findById(Long id) { 27 | return addressRepository.findOne(id); 28 | } 29 | 30 | 31 | public List
findByUserId(Long userId) { 32 | List
addresses = addressRepository.findByUserId(userId); 33 | return addresses; 34 | } 35 | 36 | public void update(Address addressInfo) { 37 | addressRepository.update(addressInfo.getId(), addressInfo); 38 | } 39 | 40 | public void delete(Long id) { 41 | addressMapper.delete(id); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/aop/AuthCheckAspect.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.aop; 2 | 3 | 4 | import com.flab.fkream.error.exception.LoginRequiredException; 5 | import com.flab.fkream.utils.SessionUtil; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.aspectj.lang.JoinPoint; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Before; 10 | import org.springframework.stereotype.Component; 11 | 12 | @Aspect 13 | @Component 14 | @Log4j2 15 | public class AuthCheckAspect { 16 | 17 | @Before("@annotation(com.flab.fkream.aop.LoginCheck) && @annotation(loginCheck)") 18 | public void loginCheck(JoinPoint joinPoint, LoginCheck loginCheck) { 19 | if (isUserType(loginCheck)) { 20 | if (!isUserLoggedIn()) { 21 | throw new LoginRequiredException(); 22 | } 23 | } 24 | } 25 | 26 | private boolean isUserType(LoginCheck loginCheck) { 27 | return LoginCheck.UserType.USER.equals(loginCheck.type()); 28 | } 29 | 30 | private boolean isUserLoggedIn() { 31 | return SessionUtil.getLoginUserId() != null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/aop/LoginCheck.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.aop; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.METHOD) 10 | public @interface LoginCheck { 11 | 12 | UserType type(); 13 | 14 | enum UserType { 15 | USER, MANAGER 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/aop/Paging.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.aop; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Target(ElementType.METHOD) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | public @interface Paging { 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/aop/PagingAspect.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.aop; 2 | 3 | 4 | import com.flab.fkream.address.Address; 5 | import com.github.pagehelper.PageHelper; 6 | import com.github.pagehelper.PageInfo; 7 | import java.util.List; 8 | import lombok.extern.log4j.Log4j2; 9 | import org.aspectj.lang.JoinPoint; 10 | import org.aspectj.lang.ProceedingJoinPoint; 11 | import org.aspectj.lang.annotation.Around; 12 | import org.aspectj.lang.annotation.Aspect; 13 | import org.springframework.stereotype.Component; 14 | 15 | @Component 16 | @Aspect 17 | @Log4j2 18 | public class PagingAspect { 19 | 20 | @Around("@annotation(com.flab.fkream.aop.Paging)") 21 | public Object paging(ProceedingJoinPoint joinPoint) throws Throwable{ 22 | int pageNum = (int)joinPoint.getArgs()[1]; 23 | int pageSize = (int)joinPoint.getArgs()[2]; 24 | if (pageNum==0 || pageSize ==0) { 25 | pageNum=1; 26 | pageSize=5; 27 | } 28 | PageHelper.startPage(pageNum, pageSize); 29 | Object result = joinPoint.proceed(); 30 | return PageInfo.of((List
)result); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/brand/Brand.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.brand; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import java.io.Serializable; 5 | import javax.validation.constraints.NotNull; 6 | import lombok.*; 7 | 8 | @Getter 9 | @ToString 10 | @EqualsAndHashCode(of = "id") 11 | @Builder 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Brand implements Serializable { 15 | 16 | private Long id; 17 | @NotNull 18 | private String brandName; 19 | @JsonProperty("luxury") 20 | private boolean luxury; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/brand/BrandController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.brand; 2 | 3 | import java.util.List; 4 | import javax.validation.Valid; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.web.bind.annotation.DeleteMapping; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PatchMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | @RestController 16 | @RequiredArgsConstructor 17 | @RequestMapping("/brands") 18 | public class BrandController { 19 | 20 | private final BrandService brandService; 21 | 22 | @PostMapping("") 23 | public void addBrand(@Valid @RequestBody Brand brandInfo) { 24 | brandService.addBrand(brandInfo); 25 | } 26 | 27 | @GetMapping("") 28 | public List findAll() { 29 | return brandService.findAll(); 30 | } 31 | 32 | @GetMapping("/{id}") 33 | public Brand findOne(@PathVariable Long id) { 34 | return brandService.findOne(id); 35 | } 36 | 37 | @PatchMapping("/{id}") 38 | public void update(@Valid @RequestBody Brand brandInfo) { 39 | brandService.update(brandInfo); 40 | } 41 | 42 | @DeleteMapping("/{id}") 43 | public void delete(@PathVariable Long id) { 44 | brandService.delete(id); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/brand/BrandService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.brand; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.BrandMapper; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | import lombok.RequiredArgsConstructor; 10 | import lombok.extern.log4j.Log4j2; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | @Service 14 | @Log4j2 15 | @RequiredArgsConstructor 16 | public class BrandService { 17 | 18 | private final BrandMapper brandMapper; 19 | 20 | 21 | public void addBrand(Brand brandInfo) { 22 | brandMapper.save(brandInfo); 23 | } 24 | 25 | public Brand findOne(Long brandId) { 26 | Brand brand = brandMapper.findOne(brandId); 27 | if (brand == null) { 28 | throw new NoDataFoundException(); 29 | } 30 | return brand; 31 | } 32 | 33 | public List findAll() { 34 | return brandMapper.findAll(); 35 | } 36 | 37 | public void update(Brand brandInfo) { 38 | brandMapper.update(brandInfo); 39 | } 40 | 41 | public void delete(Long id) { 42 | brandMapper.delete(id); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/config/CacheConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.config; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.cache.CacheManager; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.data.redis.cache.RedisCacheConfiguration; 10 | import org.springframework.data.redis.cache.RedisCacheManager; 11 | import org.springframework.data.redis.connection.RedisConnectionFactory; 12 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 13 | import org.springframework.data.redis.serializer.RedisSerializationContext; 14 | import org.springframework.data.redis.serializer.StringRedisSerializer; 15 | 16 | @Configuration 17 | @RequiredArgsConstructor 18 | public class CacheConfig { 19 | 20 | private final RedisConnectionFactory redisCacheConnectionFactory; 21 | private final ObjectMapper objectMapper; 22 | 23 | @Bean 24 | public CacheManager redisCacheManager() { 25 | RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() 26 | .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer( 27 | new StringRedisSerializer())) 28 | .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer( 29 | new GenericJackson2JsonRedisSerializer())); 30 | 31 | return RedisCacheManager 32 | .RedisCacheManagerBuilder 33 | .fromConnectionFactory(redisCacheConnectionFactory) 34 | .cacheDefaults(redisCacheConfiguration) 35 | .build(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/config/RedisCacheConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.config; 2 | 3 | 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.Profile; 10 | import org.springframework.data.redis.connection.RedisConnectionFactory; 11 | import org.springframework.data.redis.connection.RedisStandaloneConfiguration; 12 | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; 13 | import org.springframework.data.redis.core.RedisTemplate; 14 | import org.springframework.data.redis.core.ValueOperations; 15 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 16 | import org.springframework.data.redis.serializer.StringRedisSerializer; 17 | 18 | @Configuration 19 | @Profile("prod") 20 | public class RedisCacheConfig { 21 | 22 | @Value("${spring.redis.cache.host}") 23 | private String redisCacheHost; 24 | @Value("${spring.redis.cache.port}") 25 | private int redisCachePort; 26 | @Autowired 27 | public ObjectMapper objectMapper; 28 | 29 | 30 | @Bean 31 | public RedisConnectionFactory redisCacheConnectionFactory() { 32 | RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); 33 | redisStandaloneConfiguration.setHostName(redisCacheHost); 34 | redisStandaloneConfiguration.setPort(redisCachePort); 35 | return new LettuceConnectionFactory(redisStandaloneConfiguration); 36 | } 37 | 38 | @Bean 39 | public RedisTemplate redisCacheTemplate() { 40 | RedisTemplate redisTemplate = new RedisTemplate<>(); 41 | redisTemplate.setConnectionFactory(redisCacheConnectionFactory()); 42 | redisTemplate.setKeySerializer(new StringRedisSerializer()); 43 | redisTemplate.setValueSerializer(new StringRedisSerializer()); 44 | return redisTemplate; 45 | } 46 | 47 | @Bean(name = "redisValueOperations") 48 | public ValueOperations redisValueOperations() { 49 | return redisCacheTemplate().opsForValue(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/config/RedisClusterConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.config; 2 | 3 | 4 | import java.util.List; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Component 11 | @Setter 12 | @Getter 13 | @ConfigurationProperties(prefix = "redis.cluster") 14 | public class RedisClusterConfigurationProperties { 15 | 16 | List nodes; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/config/RedisSessionConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.context.annotation.Profile; 7 | import org.springframework.data.redis.connection.RedisConnectionFactory; 8 | import org.springframework.data.redis.connection.RedisStandaloneConfiguration; 9 | import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; 10 | import org.springframework.data.redis.core.RedisTemplate; 11 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 12 | import org.springframework.data.redis.serializer.StringRedisSerializer; 13 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 14 | 15 | @Configuration 16 | @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 300) 17 | @Profile("prod") 18 | public class RedisSessionConfig { 19 | 20 | @Value("${spring.redis.session.host}") 21 | private String redisSessionHost; 22 | @Value("${spring.redis.session.port}") 23 | private int redisSessionPort; 24 | 25 | 26 | // Creating Connection with Redis session 27 | @Bean({"redisConnectionFactory", "redisSessionConnectionFactory"}) 28 | public RedisConnectionFactory redisSessionConnectionFactory() { 29 | RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); 30 | redisStandaloneConfiguration.setHostName(redisSessionHost); 31 | redisStandaloneConfiguration.setPort(redisSessionPort); 32 | return new LettuceConnectionFactory(redisStandaloneConfiguration); 33 | } 34 | 35 | @Bean(name = "redisTemplate") 36 | public RedisTemplate redisSessionTemplate() { 37 | RedisTemplate redisTemplate = new RedisTemplate<>(); 38 | redisTemplate.setConnectionFactory(redisSessionConnectionFactory()); 39 | redisTemplate.setKeySerializer(new StringRedisSerializer()); 40 | redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); 41 | return redisTemplate; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/config/RedissonConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.config; 2 | 3 | 4 | import org.redisson.Redisson; 5 | import org.redisson.api.RedissonClient; 6 | import org.redisson.config.Config; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | @Configuration 12 | public class RedissonConfig { 13 | 14 | @Value("${spring.redis.redisson.host}") 15 | private String redissonHost; 16 | @Value("${spring.redis.redisson.port}") 17 | private int redissonPort; 18 | 19 | private static final String REDISSON_HOST_PREFIX = "redis://"; 20 | 21 | @Bean 22 | public RedissonClient redissonClient() { 23 | RedissonClient redisson = null; 24 | Config config = new Config(); 25 | config.useSingleServer() 26 | .setAddress(REDISSON_HOST_PREFIX + redissonHost + ":" + redissonPort); 27 | redisson = Redisson.create(config); 28 | return redisson; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/constants/Constants.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.constants; 2 | 3 | public class Constants { 4 | 5 | public static final String ShardDelimiter = "|"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/BiddingPriceDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import java.io.Serializable; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder 9 | public class BiddingPriceDto implements Serializable { 10 | 11 | private String size; 12 | 13 | private int price; 14 | 15 | private int count; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/CompleteDealPriceDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @NoArgsConstructor 10 | public class CompleteDealPriceDto { 11 | 12 | private Long itemId; 13 | private int price; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/Deal.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 4 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 5 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 6 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 7 | import com.flab.fkream.item.Item; 8 | import javax.validation.constraints.AssertTrue; 9 | import javax.validation.constraints.NotNull; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Builder; 12 | import lombok.EqualsAndHashCode; 13 | import lombok.Getter; 14 | import lombok.NoArgsConstructor; 15 | import lombok.Setter; 16 | import lombok.ToString; 17 | 18 | import java.time.LocalDate; 19 | import java.time.LocalDateTime; 20 | 21 | @Builder 22 | @Getter 23 | @ToString 24 | @AllArgsConstructor 25 | @NoArgsConstructor 26 | @EqualsAndHashCode(of = "id") 27 | public class Deal { 28 | 29 | private Long id; 30 | @NotNull 31 | @Setter 32 | private Item item; 33 | private DealType dealType; 34 | @NotNull 35 | private Long userId; 36 | @NotNull 37 | private int price; 38 | @NotNull 39 | private String size; 40 | @NotNull 41 | @JsonSerialize(using = LocalDateSerializer.class) 42 | @JsonDeserialize(using = LocalDateDeserializer.class) 43 | private LocalDate period; 44 | @AssertTrue 45 | private boolean utilizationPolicy; 46 | @AssertTrue 47 | private boolean salesCondition; 48 | private DealStatus dealStatus; 49 | @Setter 50 | private Long otherId; 51 | @JsonSerialize(using = LocalDateSerializer.class) 52 | @JsonDeserialize(using = LocalDateDeserializer.class) 53 | private LocalDateTime createdAt; 54 | @JsonSerialize(using = LocalDateSerializer.class) 55 | @JsonDeserialize(using = LocalDateDeserializer.class) 56 | private LocalDate tradingDay; 57 | 58 | public void setDealStatus(DealStatus dealStatus) { 59 | this.dealStatus = dealStatus; 60 | } 61 | 62 | public void setCreatedAtToNow() { 63 | createdAt = LocalDateTime.now(); 64 | } 65 | 66 | public void setTradingDayToNow() { 67 | tradingDay = LocalDate.now(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/DealHistoryCountDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | @Data 7 | @Builder 8 | public class DealHistoryCountDto { 9 | 10 | private DealStatus dealStatus; 11 | private int count; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/DealHistoryDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import java.time.LocalDate; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder 9 | public class DealHistoryDto { 10 | 11 | private Long dealId; 12 | private Long itemId; 13 | private String itemName; 14 | private int price; 15 | private LocalDate period; 16 | private Long itemImgId; 17 | private String imgUrl; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/DealPeriod.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import java.time.LocalDate; 4 | 5 | public enum DealPeriod { 6 | ONE_YEAR(1), 7 | SIX_MONTH(6), 8 | THREE_MONTH(3), 9 | ONE_MONTH(1); 10 | 11 | private final int value; 12 | 13 | DealPeriod(int value) { 14 | this.value = value; 15 | } 16 | 17 | public LocalDate getPeriodFromNow() { 18 | if (this == ONE_YEAR) { 19 | return LocalDate.now().minusYears(this.value); 20 | } else { 21 | return LocalDate.now().minusMonths(this.value); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/DealStatus.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | public enum DealStatus { 4 | BIDDING, IMMEDIATE, PROGRESS, CANCEL, COMPLETION, 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/DealType.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | public enum DealType { 4 | PURCHASE, SALE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/deal/MarketPriceDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.deal; 2 | 3 | import java.io.Serializable; 4 | import java.time.LocalDate; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import org.springframework.format.annotation.DateTimeFormat; 8 | 9 | @Data 10 | @Builder 11 | public class MarketPriceDto implements Serializable { 12 | 13 | 14 | private String size; 15 | 16 | private int price; 17 | 18 | @DateTimeFormat(pattern = "yyyy-MM-dd") 19 | private LocalDate tradingDay; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/ErrorMsg.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error; 2 | 3 | import com.flab.fkream.utils.HttpRequestUtils; 4 | import java.time.LocalDateTime; 5 | import lombok.Getter; 6 | import lombok.experimental.SuperBuilder; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | 10 | @Getter 11 | @SuperBuilder 12 | public class ErrorMsg { 13 | 14 | private final LocalDateTime timestamp = LocalDateTime.now(); 15 | private final String error; 16 | private final int code; 17 | private final String message; 18 | private final String path; 19 | 20 | public static ResponseEntity toResponseEntity(HttpStatus httpStatus, Exception e) { 21 | return ResponseEntity.status(httpStatus) 22 | .body( 23 | ErrorMsg.builder() 24 | .error(httpStatus.name()) 25 | .code(httpStatus.value()) 26 | .message(e.getMessage()) 27 | .path(HttpRequestUtils.getRequest().getRequestURI()) 28 | .build()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/ValidationErrorMsg.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error; 2 | 3 | import com.flab.fkream.utils.HttpRequestUtils; 4 | import java.util.List; 5 | import lombok.Getter; 6 | import lombok.experimental.SuperBuilder; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.http.ResponseEntity; 9 | 10 | @SuperBuilder 11 | @Getter 12 | public class ValidationErrorMsg extends ErrorMsg { 13 | 14 | private static final String MESSAGE = "필수 데이터를 입력해야합니다."; 15 | 16 | private final List validationMessage; 17 | 18 | public static ResponseEntity toResponseVEntity(HttpStatus httpStatus, List message) { 19 | return ResponseEntity.status(httpStatus) 20 | .body( 21 | ValidationErrorMsg.builder() 22 | .error(httpStatus.name()) 23 | .code(httpStatus.value()) 24 | .message(MESSAGE) 25 | .validationMessage(message) 26 | .path(HttpRequestUtils.getRequest().getRequestURI()) 27 | .build()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/DuplicatedEmailException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class DuplicatedEmailException extends RuntimeException { 4 | 5 | private static final String ERROR_MESSAGE = "중복된 이메일입니다."; 6 | 7 | public DuplicatedEmailException() { 8 | super(ERROR_MESSAGE); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/ForbiddenException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | import org.springframework.http.HttpStatus; 4 | import org.springframework.web.bind.annotation.ResponseStatus; 5 | 6 | @ResponseStatus(HttpStatus.FORBIDDEN) 7 | public class ForbiddenException extends RuntimeException { 8 | 9 | public ForbiddenException() { 10 | super("접근 권한이 없습니다."); 11 | } 12 | 13 | public ForbiddenException(String message) { 14 | super(message); 15 | } 16 | 17 | public ForbiddenException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public ForbiddenException(Throwable cause) { 22 | super(cause); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/GenerateAddressKeyException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class GenerateAddressKeyException extends RuntimeException { 4 | 5 | private static final String MESSAGE = "address 키 생성에 실패했습니다."; 6 | 7 | public GenerateAddressKeyException() { 8 | super(MESSAGE); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/InvalidShardKeyException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class InvalidShardKeyException extends RuntimeException { 4 | 5 | private static final String MESSAGE = "샤딩 키가 룰에 맞지 않습니다."; 6 | 7 | public InvalidShardKeyException() { 8 | super(MESSAGE); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/LoginFailureException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class LoginFailureException extends RuntimeException { 4 | 5 | private static final String LOGIN_FAILURE = "로그인 실패했습니다."; 6 | 7 | public LoginFailureException() { 8 | super(LOGIN_FAILURE); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/LoginRequiredException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class LoginRequiredException extends RuntimeException { 4 | 5 | private static final String NEED_LOGIN = "로그인이 필요합니다."; 6 | 7 | public LoginRequiredException() { 8 | super(NEED_LOGIN); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NoCardPasswordException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class NoCardPasswordException extends RuntimeException { 4 | 5 | private static final String ERROR_MESSAGE = "카드 비밀번호가 없습니다."; 6 | 7 | public NoCardPasswordException() { 8 | super(ERROR_MESSAGE); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NoDataFoundException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class NoDataFoundException extends RuntimeException { 4 | 5 | private static final String MESSAGE = "해당하는 데이터가 없습니다."; 6 | 7 | public NoDataFoundException(){ 8 | super(MESSAGE); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NoMatchDealStatusException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class NoMatchDealStatusException extends RuntimeException { 4 | 5 | private static final String MESSAGE = "입찰 및 구매, 판매 중 에러 발생"; 6 | 7 | public NoMatchDealStatusException(){ 8 | super(MESSAGE); 9 | } 10 | 11 | public NoMatchDealStatusException(String customMessage){ 12 | super(customMessage); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NoMatchDealTypeException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class NoMatchDealTypeException extends RuntimeException{ 4 | 5 | private static final String MESSAGE = "구매 및 판매 설정 오류 발생"; 6 | 7 | public NoMatchDealTypeException(){ 8 | super(MESSAGE); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NoRequestHigherPriceThenImmediatePurchaseException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class NoRequestHigherPriceThenImmediatePurchaseException extends 4 | RuntimeException { 5 | 6 | private static final String MESSAGE = "즉시 구매가 보다 높은 가격으로 설정할 수 없습니다."; 7 | 8 | public NoRequestHigherPriceThenImmediatePurchaseException() { 9 | super(MESSAGE); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NoRequestLowerPriceThenImmediateSaleException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class NoRequestLowerPriceThenImmediateSaleException extends 4 | RuntimeException { 5 | 6 | private static final String MESSAGE = "즉시 판매가 보다 낮은 가격으로 설정할 수 없습니다."; 7 | 8 | public NoRequestLowerPriceThenImmediateSaleException() { 9 | super(MESSAGE); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/NotOwnedDataException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | 4 | public class NotOwnedDataException extends RuntimeException { 5 | 6 | private static final String ERROR_MESSAGE = "해당하는 데이터는 요청자의 데이터가 아닙니다."; 7 | 8 | public NotOwnedDataException() { 9 | super(ERROR_MESSAGE); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/ShardingStrategyNotFoundException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class ShardingStrategyNotFoundException extends 4 | RuntimeException { 5 | 6 | private static final String ERROR_MESSAGE = "샤딩 전략을 찾을 수 없습니다."; 7 | 8 | public ShardingStrategyNotFoundException() { 9 | super(ERROR_MESSAGE); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/error/exception/SignUpFailureException.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.error.exception; 2 | 3 | public class SignUpFailureException extends RuntimeException{ 4 | 5 | private static final String MESSAGE = "회원가입이 실패했습니다. 다시 시도해주세요."; 6 | public SignUpFailureException(){ 7 | super(MESSAGE); 8 | } 9 | 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/interestItemCount/InterestItemCount.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.interestItemCount; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | import lombok.Setter; 8 | import org.bson.types.ObjectId; 9 | import org.springframework.data.annotation.Id; 10 | import org.springframework.data.mongodb.core.index.Indexed; 11 | import org.springframework.data.mongodb.core.mapping.Document; 12 | 13 | @Document(collection = "interestItemCount") 14 | @Getter 15 | @Setter 16 | @Builder 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class InterestItemCount { 20 | 21 | @Id 22 | private ObjectId id; 23 | @Indexed(unique = true) 24 | private Long itemId; 25 | private int count; 26 | 27 | 28 | public InterestItemCount(Long itemId, int count) { 29 | this.itemId = itemId; 30 | this.count = count; 31 | } 32 | 33 | public void increaseCount() { 34 | this.count++; 35 | } 36 | 37 | public void decreaseCount() { this.count--;} 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/interestItemCount/InterestItemCountController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.interestItemCount; 2 | 3 | import java.util.List; 4 | import lombok.RequiredArgsConstructor; 5 | import org.bson.types.ObjectId; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequiredArgsConstructor 15 | @RequestMapping("/interestItemCounts") 16 | public class InterestItemCountController { 17 | 18 | private final InterestItemCountService interestItemCountService; 19 | 20 | @GetMapping("/{itemId}") 21 | public InterestItemCount findByItemId(@PathVariable Long itemId) { 22 | return interestItemCountService.findByItemId(itemId); 23 | } 24 | 25 | @PostMapping("/increase") 26 | public void increaseCount(@RequestBody Long itemId) { 27 | interestItemCountService.increaseCount(itemId); 28 | } 29 | 30 | @PostMapping("/decrease") 31 | public void decreaseCount(@RequestBody Long itemId) { 32 | interestItemCountService.decreaseCount(itemId); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/interestItemCount/InterestItemCountRepository.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.interestItemCount; 2 | 3 | import org.springframework.data.mongodb.repository.MongoRepository; 4 | import org.springframework.stereotype.Repository; 5 | 6 | @Repository 7 | public interface InterestItemCountRepository extends MongoRepository { 8 | 9 | InterestItemCount findByItemId(Long itemId); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/interestedItem/InterestedItem.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.interestedItem; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | import lombok.ToString; 9 | 10 | @Getter 11 | @ToString 12 | @EqualsAndHashCode(of = "id") 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class InterestedItem { 17 | private Long id; 18 | private Long userId; 19 | private Long itemSizePriceId; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/interestedItem/InterestedItemController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.interestedItem; 2 | 3 | import com.flab.fkream.error.exception.ForbiddenException; 4 | import com.flab.fkream.utils.SessionUtil; 5 | import com.github.pagehelper.PageHelper; 6 | import com.github.pagehelper.PageInfo; 7 | import java.util.Objects; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.web.bind.annotation.DeleteMapping; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.RequestBody; 14 | import org.springframework.web.bind.annotation.RequestParam; 15 | import org.springframework.web.bind.annotation.ResponseStatus; 16 | import org.springframework.web.bind.annotation.RestController; 17 | 18 | @RestController 19 | @RequiredArgsConstructor 20 | public class InterestedItemController { 21 | 22 | private final InterestedItemService interestedItemService; 23 | 24 | @PostMapping("/interested-items") 25 | @ResponseStatus(HttpStatus.CREATED) 26 | public void save(@RequestBody InterestedItem interestedItemInfo) { 27 | Long loginUserId = SessionUtil.getLoginUserId(); 28 | if (!Objects.equals(loginUserId, interestedItemInfo.getUserId())) { 29 | throw new ForbiddenException(); 30 | } 31 | interestedItemService.save(interestedItemInfo); 32 | } 33 | 34 | @GetMapping("/interested-items") 35 | @ResponseStatus(HttpStatus.OK) 36 | public PageInfo findAllByUserId(@RequestParam int pageNum, @RequestParam(defaultValue = "10") int pageSize) { 37 | Long loginUserId = SessionUtil.getLoginUserId(); 38 | PageHelper.startPage(pageNum, pageSize); 39 | return PageInfo.of(interestedItemService.findAllByUserId(loginUserId)); 40 | } 41 | 42 | @DeleteMapping("/interested-items") 43 | @ResponseStatus(HttpStatus.OK) 44 | public void delete(@RequestBody InterestedItem interestedItemInfo) { 45 | Long loginUserId = SessionUtil.getLoginUserId(); 46 | Long userId = interestedItemInfo.getUserId(); 47 | Long itemSizePriceId = interestedItemInfo.getItemSizePriceId(); 48 | if (!Objects.equals(loginUserId, userId)) { 49 | throw new ForbiddenException(); 50 | } 51 | interestedItemService.delete(userId, itemSizePriceId); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/interestedItem/InterestedItemService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.interestedItem; 2 | 3 | import com.flab.fkream.interestItemCount.InterestItemCountService; 4 | import com.flab.fkream.mapper.InterestedItemMapper; 5 | import java.util.List; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.log4j.Log4j2; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | @Log4j2 12 | @RequiredArgsConstructor 13 | public class InterestedItemService { 14 | 15 | private final InterestedItemMapper interestedItemMapper; 16 | private final InterestItemCountService interestItemCountService; 17 | 18 | public void save(InterestedItem interestedItem) { 19 | InterestedItem foundInterestedItem = interestedItemMapper.findByUserIdAndItemSizePriceId( 20 | interestedItem.getUserId(), 21 | interestedItem.getItemSizePriceId()); 22 | 23 | if (foundInterestedItem != null) { 24 | throw new IllegalArgumentException(); 25 | } 26 | 27 | interestedItemMapper.save(interestedItem); 28 | } 29 | 30 | public List findAllByUserId(Long userId) { 31 | return interestedItemMapper.findAllByUserId(userId); 32 | } 33 | 34 | public void delete(Long userId, Long itemSizePriceId) { 35 | InterestedItem foundInterestedItem = interestedItemMapper.findByUserIdAndItemSizePriceId( 36 | userId, itemSizePriceId); 37 | 38 | if (foundInterestedItem == null) { 39 | throw new IllegalArgumentException(); 40 | } 41 | 42 | interestedItemMapper.deleteById(userId, itemSizePriceId); 43 | interestItemCountService.decreaseCount(foundInterestedItem.getItemSizePriceId()); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/item/Item.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.item; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; 9 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 10 | import com.flab.fkream.itemCategory.ItemCategory; 11 | import java.time.LocalDate; 12 | import java.time.LocalDateTime; 13 | 14 | import com.flab.fkream.brand.Brand; 15 | import javax.validation.constraints.NotNull; 16 | import lombok.*; 17 | import org.springframework.format.annotation.DateTimeFormat; 18 | 19 | @Getter 20 | @ToString 21 | @EqualsAndHashCode(of = "id") 22 | @Builder 23 | @NoArgsConstructor 24 | @AllArgsConstructor 25 | public class Item { 26 | 27 | private Long id; 28 | @NotNull 29 | private String itemName; 30 | @NotNull 31 | private String modelNumber; 32 | @NotNull 33 | private Long categoryId; 34 | @NotNull 35 | private Long detailedCategoryId; 36 | 37 | @DateTimeFormat(pattern = "yyyy-MM-dd") 38 | @JsonSerialize(using = LocalDateSerializer.class) 39 | @JsonDeserialize(using = LocalDateDeserializer.class) 40 | private LocalDate releaseDate; 41 | 42 | @NotNull 43 | private String representativeColor; 44 | @NotNull 45 | private int releasedPrice; 46 | 47 | @NotNull 48 | private ItemGender gender; 49 | @NotNull 50 | private Brand brand; 51 | 52 | private Long managerId; 53 | 54 | private int latestPrice; 55 | 56 | private boolean oneSize; 57 | 58 | @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) 59 | private LocalDateTime createdAt; 60 | 61 | @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) 62 | private LocalDateTime modifiedAt; 63 | 64 | public void setCreatedAtToNow() { 65 | createdAt = LocalDateTime.now(); 66 | } 67 | 68 | public void setModifiedAtToNow() { 69 | modifiedAt = LocalDateTime.now(); 70 | } 71 | 72 | public void setBrand(Brand brand) { 73 | this.brand = brand; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/item/ItemController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.item; 2 | 3 | import java.util.List; 4 | import lombok.NonNull; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.web.bind.annotation.DeleteMapping; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PatchMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestBody; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.ResponseStatus; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | @RestController 18 | @RequiredArgsConstructor 19 | @RequestMapping("/items") 20 | public class ItemController { 21 | 22 | private final ItemService itemService; 23 | 24 | // item 추가 25 | @PostMapping("") 26 | public HttpStatus addItem(@RequestBody @NonNull Item itemInfo) { 27 | itemService.addItem(itemInfo); 28 | return HttpStatus.CREATED; 29 | } 30 | 31 | // item 리스트 조회 32 | @GetMapping("") 33 | public List findAll() { 34 | return itemService.findAll(); 35 | } 36 | 37 | // item 단건 조회 38 | @GetMapping("/{id}") 39 | public Item findOne(@PathVariable Long id) { 40 | return itemService.findOne(id); 41 | } 42 | 43 | // item 수정 44 | @PatchMapping("/{id}") 45 | @ResponseStatus(HttpStatus.OK) 46 | public void update(@RequestBody Item itemInfo) { 47 | itemService.update(itemInfo); 48 | } 49 | 50 | // item 삭제 51 | @DeleteMapping("/{id}") 52 | @ResponseStatus(HttpStatus.OK) 53 | public void delete(@PathVariable Long id) { 54 | itemService.delete(id); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/item/ItemGender.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.item; 2 | 3 | public enum ItemGender { 4 | MALE, FEMALE, KIDS 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemCategory/ItemCategory.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | import java.io.Serializable; 4 | import javax.validation.constraints.NotNull; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Builder 13 | @Getter 14 | @EqualsAndHashCode 15 | @ToString 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class ItemCategory implements Serializable { 19 | 20 | private Long id; 21 | @NotNull 22 | private String name; 23 | private Long parentId; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemCategory/ItemCategoryController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | 4 | import java.util.List; 5 | import javax.validation.Valid; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.web.bind.annotation.DeleteMapping; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.PathVariable; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | @RestController 16 | @RequiredArgsConstructor 17 | @RequestMapping("/categories") 18 | public class ItemCategoryController { 19 | 20 | private final ItemCategoryService itemCategoryService; 21 | 22 | 23 | @PostMapping("") 24 | public void addCategory(@Valid @RequestBody ItemCategory itemCategory) { 25 | itemCategoryService.addCategory(itemCategory); 26 | } 27 | 28 | @GetMapping("") 29 | public List findAll() { 30 | return itemCategoryService.findAllCategory(); 31 | } 32 | 33 | @DeleteMapping("/{id}") 34 | public void delete(@PathVariable Long id) { 35 | itemCategoryService.delete(id); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemCategory/ItemCategoryDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | import java.util.List; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class ItemCategoryDto { 8 | 9 | private Long id; 10 | private String name; 11 | private List detailedCategories; 12 | 13 | public ItemCategoryDto(ItemCategory itemCategory, List detailedCategories) { 14 | this.id = itemCategory.getId(); 15 | this.name = itemCategory.getName(); 16 | this.detailedCategories = detailedCategories; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemCategory/ItemCategoryService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.ItemCategoryMapper; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import lombok.RequiredArgsConstructor; 8 | import lombok.extern.log4j.Log4j2; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | @Log4j2 13 | @RequiredArgsConstructor 14 | public class ItemCategoryService { 15 | 16 | private final ItemCategoryMapper itemCategoryMapper; 17 | 18 | public void addCategory(ItemCategory category) { 19 | itemCategoryMapper.save(category); 20 | } 21 | 22 | public ItemCategory findById(Long id) { 23 | ItemCategory itemCategory = itemCategoryMapper.findById(id); 24 | if (itemCategory == null) { 25 | throw new NoDataFoundException(); 26 | } 27 | return itemCategory; 28 | } 29 | 30 | public List findAllCategory() { 31 | List itemCategoryDtos = new ArrayList<>(); 32 | List parentCategories = itemCategoryMapper.findParentCategory(); 33 | 34 | for (ItemCategory parentCategory : parentCategories) { 35 | List childCategories = itemCategoryMapper.findChildCategory( 36 | parentCategory.getId()); 37 | itemCategoryDtos.add(new ItemCategoryDto(parentCategory, childCategories)); 38 | } 39 | return itemCategoryDtos; 40 | } 41 | 42 | public void delete(Long id) { 43 | itemCategoryMapper.delete(id); 44 | } 45 | 46 | /** 47 | * 부모 카테고리가 있으면 해당 부모의 자식 카테고리가 있으면 안된다. 48 | */ 49 | public boolean isValidCategoryId(Long[] categoryId) { 50 | if (categoryId==null){ 51 | return true; 52 | } 53 | List categories = List.of(categoryId); 54 | for (Long id : categories) { 55 | ItemCategory itemCategory = findById(id); 56 | if (itemCategory.getParentId() != null && categories.contains( 57 | itemCategory.getParentId())) { 58 | return false; 59 | } 60 | } 61 | return true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemImg/ItemImg.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemImg; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import com.flab.fkream.item.Item; 6 | import javax.validation.constraints.NotNull; 7 | import lombok.*; 8 | import org.springframework.format.annotation.DateTimeFormat; 9 | 10 | @Getter 11 | @ToString 12 | @EqualsAndHashCode(of = "id") 13 | @Builder 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class ItemImg { 17 | 18 | private Long id; 19 | @NotNull 20 | private Item item; 21 | @NotNull 22 | private String imgName; 23 | @NotNull 24 | private String imgUrl; 25 | @NotNull 26 | private String originName; 27 | private boolean representativeImg; 28 | 29 | @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) 30 | private LocalDateTime createdAt; 31 | 32 | public void setCreatedAtToNow() { 33 | createdAt = LocalDateTime.now(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemImg/ItemImgController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemImg; 2 | 3 | import java.util.List; 4 | 5 | import com.flab.fkream.brand.Brand; 6 | import javax.validation.Valid; 7 | import org.springframework.http.HttpStatus; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import lombok.RequiredArgsConstructor; 11 | 12 | @RestController 13 | @RequiredArgsConstructor 14 | @RequestMapping("") 15 | public class ItemImgController { 16 | 17 | private final ItemImgService itemImgService; 18 | 19 | @PostMapping("/itemImgs") 20 | public HttpStatus addItemImg(@Valid @RequestBody ItemImg itemImgInfo) { 21 | itemImgService.addItemImg(itemImgInfo); 22 | return HttpStatus.CREATED; 23 | } 24 | 25 | @GetMapping("/itemImgs/{itemId}") 26 | public List findImagesByItemId(@PathVariable Long itemId) { 27 | return itemImgService.findImagesByItemId(itemId); 28 | } 29 | 30 | @DeleteMapping("/itemImgs/{id}") 31 | @ResponseStatus(HttpStatus.OK) 32 | public void delete(@PathVariable Long id) { 33 | itemImgService.delete(id); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemImg/ItemImgService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemImg; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.ItemImgMapper; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | import lombok.RequiredArgsConstructor; 10 | import lombok.extern.log4j.Log4j2; 11 | 12 | @Service 13 | @Log4j2 14 | @RequiredArgsConstructor 15 | public class ItemImgService { 16 | 17 | private final ItemImgMapper itemImgMapper; 18 | 19 | public void addItemImg(ItemImg itemImgInfo) { 20 | itemImgInfo.setCreatedAtToNow(); 21 | itemImgMapper.save(itemImgInfo); 22 | } 23 | 24 | public List findImagesByItemId(Long itemId) { 25 | List itemImages = itemImgMapper.findImagesByItemId(itemId); 26 | return itemImages; 27 | } 28 | 29 | public ItemImg findRepresentImageByItemID(Long itemId) { 30 | List imagesByItemId = itemImgMapper.findImagesByItemId(itemId); 31 | for (ItemImg itemImg : imagesByItemId) { 32 | if (itemImg.isRepresentativeImg()) { 33 | return itemImg; 34 | } 35 | } 36 | throw new NoDataFoundException(); 37 | } 38 | 39 | public void delete(Long id) { 40 | itemImgMapper.delete(id); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemSizePrice/ItemSizePrice.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemSizePrice; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import javax.validation.constraints.NotNull; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.Setter; 12 | import lombok.ToString; 13 | 14 | @Getter 15 | @ToString 16 | @EqualsAndHashCode(of = "id") 17 | @Builder 18 | @NoArgsConstructor 19 | @AllArgsConstructor 20 | public class ItemSizePrice { 21 | private Long id; 22 | @NotNull 23 | private Long itemId; 24 | private String size; 25 | @Setter 26 | private Integer immediatePurchasePrice; 27 | @Setter 28 | private Integer immediateSalePrice; 29 | private LocalDateTime modifiedAt; 30 | 31 | public void changePrice(Integer immediateSalePrice, Integer immediatePurchasePrice) { 32 | this.immediateSalePrice = immediateSalePrice; 33 | this.immediatePurchasePrice = immediatePurchasePrice; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemSizePrice/ItemSizePriceController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemSizePrice; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.DeleteMapping; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.PostMapping; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import lombok.RequiredArgsConstructor; 16 | 17 | @RestController 18 | @RequiredArgsConstructor 19 | @RequestMapping("/itemSizePrices") 20 | public class ItemSizePriceController { 21 | private final ItemSizePriceService itemSizePriceService; 22 | 23 | @PostMapping("") 24 | public HttpStatus addItemSizePrice(@RequestBody ItemSizePrice itemSizePriceInfo) { 25 | itemSizePriceService.addItemSizePrice(itemSizePriceInfo); 26 | return HttpStatus.CREATED; 27 | } 28 | 29 | @GetMapping("/{id}") 30 | public ItemSizePrice findOne(@PathVariable Long id) { 31 | return itemSizePriceService.findOne(id); 32 | } 33 | 34 | @GetMapping("/byItemId/{itemId}") 35 | public List findAllByItemId(@PathVariable Long itemId) { 36 | return itemSizePriceService.findAllByItemId(itemId); 37 | } 38 | 39 | @GetMapping("/byItemIdAndSize") 40 | public ItemSizePrice findByItemIdAndSize(@RequestParam Long itemId, @RequestParam String size) { 41 | return itemSizePriceService.findByItemIdAndSize(itemId, size); 42 | } 43 | 44 | @DeleteMapping("/{id}") 45 | public void delete(@PathVariable Long id){ 46 | itemSizePriceService.delete(id); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/itemSizePrice/ItemSizePriceService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemSizePrice; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.ItemSizePriceMapper; 5 | import java.util.List; 6 | 7 | import org.springframework.stereotype.Service; 8 | 9 | import lombok.RequiredArgsConstructor; 10 | import lombok.extern.log4j.Log4j2; 11 | 12 | @Service 13 | @Log4j2 14 | @RequiredArgsConstructor 15 | public class ItemSizePriceService { 16 | 17 | private final ItemSizePriceMapper itemSizePriceMapper; 18 | 19 | public void addItemSizePrice(ItemSizePrice itemSizePriceInfo) { 20 | itemSizePriceMapper.save(itemSizePriceInfo); 21 | } 22 | 23 | public ItemSizePrice findOne(Long id) { 24 | ItemSizePrice itemSizePrice = itemSizePriceMapper.findOne(id); 25 | if (itemSizePrice == null) { 26 | throw new NoDataFoundException(); 27 | } 28 | return itemSizePrice; 29 | } 30 | 31 | public List findAllByItemId(Long itemId) { 32 | List itemSizePrices = itemSizePriceMapper.findAllByItemId(itemId); 33 | return itemSizePrices; 34 | } 35 | 36 | public ItemSizePrice findByItemIdAndSize(Long itemId, String size) { 37 | ItemSizePrice itemSizePrice = itemSizePriceMapper.findByItemIdAndSize(itemId, size); 38 | if (itemSizePrice == null) { 39 | throw new NoDataFoundException(); 40 | } 41 | return itemSizePrice; 42 | } 43 | 44 | public void delete(Long id) { 45 | itemSizePriceMapper.delete(id); 46 | } 47 | 48 | 49 | public void update(ItemSizePrice itemSizePrice) { 50 | itemSizePriceMapper.update(itemSizePrice); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/kafka/KafkaConsumeConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.kafka; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import org.apache.kafka.clients.consumer.ConsumerConfig; 6 | import org.apache.kafka.common.serialization.StringDeserializer; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; 11 | import org.springframework.kafka.core.ConsumerFactory; 12 | import org.springframework.kafka.core.DefaultKafkaConsumerFactory; 13 | import org.springframework.kafka.support.serializer.JsonDeserializer; 14 | 15 | @Configuration 16 | public class KafkaConsumeConfig { 17 | 18 | @Value("${spring.kafka.bootstrap-servers}") 19 | private String bootstrapServers; 20 | 21 | @Value("${spring.kafka.group-id}") 22 | private String groupId; 23 | 24 | @Bean 25 | public ConsumerFactory consumerFactory() { 26 | return new DefaultKafkaConsumerFactory<>(consumerFactoryConfig()); 27 | } 28 | 29 | private Map consumerFactoryConfig() { 30 | Map props = new HashMap<>(); 31 | props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 32 | props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); 33 | props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 34 | props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class); 35 | props.put(JsonDeserializer.TRUSTED_PACKAGES, "*"); 36 | return props; 37 | } 38 | 39 | @Bean 40 | public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { 41 | ConcurrentKafkaListenerContainerFactory listenerContainerFactory 42 | = new ConcurrentKafkaListenerContainerFactory<>(); 43 | listenerContainerFactory.setConsumerFactory(consumerFactory()); 44 | return listenerContainerFactory; 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/kafka/KafkaMessageSender.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.kafka; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | import java.time.LocalDateTime; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.apache.kafka.clients.producer.ProducerRecord; 8 | import org.apache.kafka.common.header.internals.RecordHeader; 9 | import org.springframework.kafka.core.KafkaTemplate; 10 | import org.springframework.kafka.support.SendResult; 11 | import org.springframework.stereotype.Component; 12 | import org.springframework.util.concurrent.ListenableFuture; 13 | import org.springframework.util.concurrent.ListenableFutureCallback; 14 | 15 | @Component 16 | @RequiredArgsConstructor 17 | @Log4j2 18 | public class KafkaMessageSender { 19 | 20 | private final KafkaTemplate kafkaTemplate; 21 | 22 | public void send(String topic, Object data) { 23 | ProducerRecord record = new ProducerRecord<>(topic, data); 24 | ListenableFuture> future = kafkaTemplate.send( 25 | record); 26 | 27 | future.addCallback(new ListenableFutureCallback>() { 28 | @Override 29 | public void onFailure(Throwable ex) { 30 | log.error("메세지 전송 실패"); 31 | } 32 | 33 | @Override 34 | public void onSuccess(SendResult result) { 35 | log.info("메세지 전송 성공"); 36 | } 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/kafka/KafkaProducerConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.kafka; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import org.apache.kafka.clients.producer.ProducerConfig; 6 | import org.apache.kafka.common.serialization.StringSerializer; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.kafka.annotation.EnableKafka; 11 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 12 | import org.springframework.kafka.core.KafkaTemplate; 13 | import org.springframework.kafka.core.ProducerFactory; 14 | import org.springframework.kafka.support.serializer.JsonSerializer; 15 | 16 | @Configuration 17 | @EnableKafka 18 | public class KafkaProducerConfig { 19 | 20 | @Value("${spring.kafka.bootstrap-servers}") 21 | private String bootstrapServers; 22 | 23 | @Bean 24 | public ProducerFactory producerFactory() { 25 | Map configProps = producerFactoryConfig(); 26 | return new DefaultKafkaProducerFactory<>(configProps); 27 | } 28 | 29 | private Map producerFactoryConfig() { 30 | Map configProps = new HashMap<>(); 31 | configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 32 | configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 33 | configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); 34 | return configProps; 35 | } 36 | 37 | @Bean 38 | public KafkaTemplate kafkaTemplate() { 39 | return new KafkaTemplate<>(producerFactory()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/kafka/KafkaTopic.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.kafka; 2 | 3 | public class KafkaTopic { 4 | 5 | public static final String ITEM_TOPIC = "item"; 6 | public static final String SEARCH_LOG = "search_log"; 7 | public static final String DEAL = "deal"; 8 | public static final String ITEM_PURCHASE_PRICE = "item_purchase_price"; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/kafka/KafkaTopicConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.kafka; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import org.apache.kafka.clients.admin.AdminClientConfig; 6 | import org.apache.kafka.clients.admin.NewTopic; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.kafka.core.KafkaAdmin; 11 | 12 | /** 13 | * 토픽 생성 14 | */ 15 | 16 | @Configuration 17 | public class KafkaTopicConfig { 18 | @Value("${spring.kafka.bootstrap-servers}") 19 | private String bootstrapServers; 20 | 21 | public final static String COMPLETION_DEAL_PRICE = "complete_deal_price"; 22 | 23 | 24 | @Bean 25 | public KafkaAdmin kafkaAdmin() { 26 | Map configs = new HashMap<>(); 27 | configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); 28 | return new KafkaAdmin(configs); 29 | } 30 | 31 | @Bean 32 | public NewTopic newTopic() { 33 | return new NewTopic(COMPLETION_DEAL_PRICE, 1, (short) 3); 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerateStrategy/ItemsBelowReleasedPriceStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing.ItemGenerateStrategy; 2 | 3 | import com.flab.fkream.listing.ItemGenerationStrategy; 4 | import com.flab.fkream.listing.ListingCriteria; 5 | import com.flab.fkream.mapper.ListingMapper; 6 | import com.flab.fkream.search.dbSearch.SearchItemDto; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | @RequiredArgsConstructor 13 | public class ItemsBelowReleasedPriceStrategy implements ItemGenerationStrategy { 14 | 15 | private final ListingCriteria criteria = ListingCriteria.ITEMS_BELOW_RELEASED_PRICE; 16 | 17 | private final ListingMapper listingMapper; 18 | 19 | @Override 20 | public List generateItems(int month) { 21 | List searchItemDtos = listingMapper.generateItemsBelowReleasedPrice(month); 22 | return searchItemDtos; 23 | } 24 | 25 | @Override 26 | public ListingCriteria getCriteria() { 27 | return criteria; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerateStrategy/MostPopularStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing.ItemGenerateStrategy; 2 | 3 | import com.flab.fkream.listing.ItemGenerationStrategy; 4 | import com.flab.fkream.listing.ListingCriteria; 5 | import com.flab.fkream.mapper.ListingMapper; 6 | import com.flab.fkream.search.dbSearch.SearchItemDto; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.stereotype.Component; 10 | 11 | @RequiredArgsConstructor 12 | @Component 13 | public class MostPopularStrategy implements ItemGenerationStrategy { 14 | 15 | private final ListingCriteria criteria = ListingCriteria.MOST_POPULAR; 16 | private final ListingMapper listingMapper; 17 | 18 | @Override 19 | public List generateItems(int month) { 20 | return listingMapper.generateMostPopularItems(); 21 | } 22 | 23 | @Override 24 | public ListingCriteria getCriteria() { 25 | return criteria; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerateStrategy/PopularLuxuryItemsStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing.ItemGenerateStrategy; 2 | 3 | import com.flab.fkream.listing.ItemGenerationStrategy; 4 | import com.flab.fkream.listing.ListingCriteria; 5 | import com.flab.fkream.mapper.ListingMapper; 6 | import com.flab.fkream.search.dbSearch.SearchItemDto; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.stereotype.Component; 10 | 11 | @RequiredArgsConstructor 12 | @Component 13 | public class PopularLuxuryItemsStrategy implements ItemGenerationStrategy { 14 | 15 | private final ListingCriteria criteria = ListingCriteria.POPULAR_LUXURY_ITEMS; 16 | 17 | private final ListingMapper listingMapper; 18 | 19 | @Override 20 | public List generateItems(int month) { 21 | List searchItemDtos = listingMapper.generatePopularLuxuryItems(month); 22 | return searchItemDtos; 23 | } 24 | 25 | @Override 26 | public ListingCriteria getCriteria() { 27 | return criteria; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerateStrategy/PopularSneakersStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing.ItemGenerateStrategy; 2 | 3 | import com.flab.fkream.listing.ItemGenerationStrategy; 4 | import com.flab.fkream.listing.ListingCriteria; 5 | import com.flab.fkream.mapper.ListingMapper; 6 | import com.flab.fkream.search.dbSearch.SearchItemDto; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.stereotype.Component; 10 | 11 | @RequiredArgsConstructor 12 | @Component 13 | public class PopularSneakersStrategy implements ItemGenerationStrategy { 14 | 15 | private final ListingCriteria criteria = ListingCriteria.POPULAR_SNEAKERS; 16 | 17 | private final ListingMapper listingMapper; 18 | 19 | @Override 20 | public List generateItems(int month) { 21 | return listingMapper.generatePopularSneakers(month); 22 | } 23 | 24 | @Override 25 | public ListingCriteria getCriteria() { 26 | return criteria; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerateStrategy/RecommendedItemForMenStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing.ItemGenerateStrategy; 2 | 3 | import com.flab.fkream.listing.ItemGenerationStrategy; 4 | import com.flab.fkream.listing.ListingCriteria; 5 | import com.flab.fkream.mapper.ListingMapper; 6 | import com.flab.fkream.search.dbSearch.SearchItemDto; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.stereotype.Component; 10 | 11 | @RequiredArgsConstructor 12 | @Component 13 | public class RecommendedItemForMenStrategy implements ItemGenerationStrategy { 14 | 15 | private final ListingCriteria criteria = ListingCriteria.RECOMMENDED_ITEM_FOR_MEN; 16 | 17 | private final ListingMapper listingMapper; 18 | 19 | @Override 20 | public List generateItems(int month) { 21 | List searchItemDtos = listingMapper.generateRecommendedItemsForMen(month); 22 | return searchItemDtos; 23 | } 24 | 25 | @Override 26 | public ListingCriteria getCriteria() { 27 | return criteria; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerateStrategy/RecommendedItemForWomenStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing.ItemGenerateStrategy; 2 | 3 | import com.flab.fkream.listing.ItemGenerationStrategy; 4 | import com.flab.fkream.listing.ListingCriteria; 5 | import com.flab.fkream.mapper.ListingMapper; 6 | import com.flab.fkream.search.dbSearch.SearchItemDto; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.stereotype.Component; 10 | 11 | 12 | @RequiredArgsConstructor 13 | @Component 14 | public class RecommendedItemForWomenStrategy implements ItemGenerationStrategy { 15 | 16 | private final ListingCriteria criteria = ListingCriteria.RECOMMENDED_ITEM_FOR_WOMEN; 17 | private final ListingMapper listingMapper; 18 | 19 | @Override 20 | public List generateItems(int month) { 21 | List searchItemDtos = listingMapper.generateRecommendedItemsForWomen(month); 22 | return searchItemDtos; 23 | } 24 | 25 | @Override 26 | public ListingCriteria getCriteria() { 27 | return criteria; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerationStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing; 2 | 3 | import com.flab.fkream.search.dbSearch.SearchItemDto; 4 | import java.util.List; 5 | 6 | public interface ItemGenerationStrategy { 7 | List generateItems(int month); 8 | 9 | ListingCriteria getCriteria(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ItemGenerationStrategyFactory.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Set; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Component 12 | public class ItemGenerationStrategyFactory { 13 | 14 | private final Map strategies; 15 | 16 | @Autowired 17 | public ItemGenerationStrategyFactory(List itemGenerationStrategies) { 18 | this.strategies = new HashMap<>(); 19 | for (ItemGenerationStrategy itemGenerationStrategy : itemGenerationStrategies) { 20 | strategies.put(itemGenerationStrategy.getCriteria(), itemGenerationStrategy); 21 | } 22 | } 23 | 24 | public ItemGenerationStrategy get(ListingCriteria listingCriteria) { 25 | return strategies.get(listingCriteria); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ListingController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing; 2 | 3 | import com.flab.fkream.search.dbSearch.SearchItemDto; 4 | import java.util.List; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @RestController 11 | @RequestMapping("/listing") 12 | @RequiredArgsConstructor 13 | public class ListingController { 14 | 15 | private final ListingService listingService; 16 | 17 | @GetMapping 18 | public List generateItems(ListingCriteria listingCriteria) { 19 | return listingService.generateItems(listingCriteria); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ListingCriteria.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing; 2 | 3 | public enum ListingCriteria { 4 | 5 | RECOMMENDED_ITEM_FOR_MEN, RECOMMENDED_ITEM_FOR_WOMEN, MOST_POPULAR, 6 | POPULAR_SNEAKERS, ITEMS_BELOW_RELEASED_PRICE, POPULAR_LUXURY_ITEMS 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/listing/ListingService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.listing; 2 | 3 | import com.flab.fkream.search.dbSearch.SearchItemDto; 4 | import java.util.List; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.extern.log4j.Log4j2; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | @RequiredArgsConstructor 11 | @Log4j2 12 | public class ListingService { 13 | 14 | private final ItemGenerationStrategyFactory itemGenerationStrategyFactory; 15 | 16 | public List generateItems(ListingCriteria listingCriteria) { 17 | final int month = 1; 18 | ItemGenerationStrategy strategy = itemGenerationStrategyFactory.get(listingCriteria); 19 | if (strategy == null) { 20 | throw new IllegalArgumentException("리스팅 기준이 잘못 입력되었습니다."); 21 | } 22 | return strategy.generateItems(month); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/login/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.login; 2 | 3 | import static com.flab.fkream.aop.LoginCheck.UserType; 4 | 5 | import com.flab.fkream.aop.LoginCheck; 6 | import com.flab.fkream.user.User; 7 | import com.flab.fkream.user.UserService; 8 | import com.flab.fkream.utils.SessionUtil; 9 | import javax.servlet.http.HttpSession; 10 | import lombok.RequiredArgsConstructor; 11 | import lombok.extern.log4j.Log4j2; 12 | import org.springframework.http.HttpStatus; 13 | import org.springframework.web.bind.annotation.GetMapping; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.RequestBody; 16 | import org.springframework.web.bind.annotation.ResponseStatus; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | @RestController 20 | @RequiredArgsConstructor 21 | @Log4j2 22 | public class LoginController { 23 | 24 | private final UserService userService; 25 | 26 | @PostMapping("/login") 27 | @ResponseStatus(HttpStatus.OK) 28 | public void login(@RequestBody LoginForm loginForm, HttpSession httpSession) { 29 | User user = userService.login(loginForm); 30 | SessionUtil.setLoginUserId(httpSession, user.getId()); 31 | } 32 | 33 | @GetMapping("/logout") 34 | @ResponseStatus(HttpStatus.OK) 35 | @LoginCheck(type = UserType.USER) 36 | public void logout(HttpSession session) { 37 | SessionUtil.logoutUser(session); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/login/LoginForm.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.login; 2 | 3 | import lombok.*; 4 | 5 | @NoArgsConstructor 6 | @AllArgsConstructor 7 | @Getter 8 | @Setter 9 | @EqualsAndHashCode 10 | public class LoginForm { 11 | 12 | private String email; 13 | private String password; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/manager/Manager.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.manager; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @ToString 14 | @EqualsAndHashCode(of = "id") 15 | @Builder 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class Manager { 19 | private Long id; 20 | private String employeeNumber; 21 | private String password; 22 | private String name; 23 | private String phoneNumber; 24 | private String agreement; 25 | private LocalDateTime createdAt; 26 | private LocalDateTime modifiedAt; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/manager/ManagerController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.manager; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import lombok.RequiredArgsConstructor; 14 | 15 | @RestController 16 | @RequiredArgsConstructor 17 | @RequestMapping("/managers") 18 | public class ManagerController { 19 | private final ManagerService managerService; 20 | 21 | @PostMapping("") 22 | public HttpStatus addManager(@RequestBody Manager managerInfo) { 23 | managerService.addManager(managerInfo); 24 | return HttpStatus.CREATED; 25 | } 26 | 27 | @GetMapping("") 28 | public List findAll() { 29 | return managerService.findAll(); 30 | } 31 | 32 | @GetMapping("/{id}") 33 | public Manager findOne(@PathVariable Long id) { 34 | return managerService.findOne(id); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/manager/ManagerService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.manager; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.ManagerMapper; 5 | import java.util.List; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.log4j.Log4j2; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | @Log4j2 12 | @RequiredArgsConstructor 13 | public class ManagerService { 14 | 15 | private final ManagerMapper managerMapper; 16 | 17 | public void addManager(Manager managerInfo) { 18 | managerMapper.save(managerInfo); 19 | } 20 | 21 | public Manager findOne(Long managerId) { 22 | Manager manager = managerMapper.findOne(managerId); 23 | if (manager == null) { 24 | throw new NoDataFoundException(); 25 | } 26 | return manager; 27 | } 28 | 29 | public List findAll() { 30 | List managers = managerMapper.findAll(); 31 | return managers; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/AddressMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.address.Address; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.cache.annotation.CacheEvict; 7 | import org.springframework.cache.annotation.Cacheable; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | @Mapper 11 | public interface AddressMapper { 12 | 13 | int save(Address address); 14 | 15 | //@Transactional(readOnly = true) 16 | Address findOne(Long id); 17 | 18 | @Transactional(readOnly = true) 19 | @Cacheable(cacheNames = "AddressByUserId", key = "#p0") 20 | List
findByUserId(Long userId); 21 | 22 | @CacheEvict(cacheNames = "AddressByUserId", key = "#p0.userId") 23 | int update(Address addressInfo); 24 | 25 | int delete(Long id); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/BrandMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.brand.Brand; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.cache.annotation.CacheEvict; 7 | import org.springframework.cache.annotation.Cacheable; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | @Mapper 11 | public interface BrandMapper { 12 | 13 | int save(Brand brand); 14 | 15 | //@Cacheable(cacheNames = "Brand", key = "#p0") 16 | @Transactional(readOnly = true) 17 | Brand findOne(Long id); 18 | 19 | List findAll(); 20 | 21 | @CacheEvict(cacheNames = "Brand", key = "#p0.id") 22 | int update(Brand brandInfo); 23 | 24 | int delete(Long id); 25 | 26 | Brand findByBrandName(String brandName); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/DealMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.deal.BiddingPriceDto; 4 | import com.flab.fkream.deal.Deal; 5 | import com.flab.fkream.deal.DealHistoryCountDto; 6 | import com.flab.fkream.deal.DealHistoryDto; 7 | import com.flab.fkream.deal.DealStatus; 8 | import com.flab.fkream.deal.DealType; 9 | import com.flab.fkream.deal.MarketPriceDto; 10 | import java.time.LocalDate; 11 | import java.util.List; 12 | import org.apache.ibatis.annotations.Mapper; 13 | import org.springframework.transaction.annotation.Transactional; 14 | 15 | @Mapper 16 | public interface DealMapper { 17 | 18 | int save(Deal deal); 19 | 20 | @Transactional(readOnly = true) 21 | List findByUserId(Long userId); 22 | 23 | @Transactional(readOnly = true) 24 | Deal findById(Long id); 25 | 26 | int update(Deal deal); 27 | 28 | int delete(Long id); 29 | 30 | @Transactional(readOnly = true) 31 | Deal findBuyNowDealByItemIdAndSizeAndPrice(Long id, String size, int price); 32 | 33 | @Transactional(readOnly = true) 34 | Deal findSellNowDealByItemIdAndSizeAndPrice(Long id, String size, int price); 35 | 36 | @Transactional(readOnly = true) 37 | Integer findHighestPurchasePriceByItemIdAndSize(Long itemId, String size); 38 | 39 | @Transactional(readOnly = true) 40 | Integer findLowestSalePriceByItemIdAndSize(Long itemId, String size); 41 | 42 | @Transactional(readOnly = true) 43 | List findMarketPrices(Long itemId, String size); 44 | 45 | @Transactional(readOnly = true) 46 | List findMarketPricesInGraph(Long itemId, LocalDate period, String size); 47 | 48 | @Transactional(readOnly = true) 49 | List findBiddingPrices(Long itemId, String size, DealType dealType); 50 | 51 | @Transactional(readOnly = true) 52 | List findHistoryCount(Long userId, DealType dealType); 53 | 54 | @Transactional(readOnly = true) 55 | List findPurchaseHistories(Long userId, DealStatus dealStatus); 56 | 57 | @Transactional(readOnly = true) 58 | List findSaleHistories(Long userId, DealStatus dealStatus); 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/InterestedItemMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.interestedItem.InterestedItem; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.apache.ibatis.annotations.Param; 7 | 8 | @Mapper 9 | public interface InterestedItemMapper { 10 | 11 | int save(InterestedItem interestedItem); 12 | 13 | InterestedItem findByUserIdAndItemSizePriceId(Long userId, Long itemSizePriceId); 14 | 15 | List findAllByUserId(Long userId); 16 | 17 | int deleteById(@Param("userId") Long userId, @Param("itemSizePriceId") Long itemSizePriceId); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/ItemCategoryMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.itemCategory.ItemCategory; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.cache.annotation.CacheEvict; 7 | import org.springframework.cache.annotation.Cacheable; 8 | import org.springframework.cache.annotation.Caching; 9 | 10 | @Mapper 11 | public interface ItemCategoryMapper { 12 | 13 | int save(ItemCategory category); 14 | 15 | //@Cacheable(cacheNames = "ItemCategoryAll", key = "#root.methodName") 16 | List findParentCategory(); 17 | 18 | //@Cacheable(cacheNames = "ItemCategoryAll", key = "#p0") 19 | List findChildCategory(Long parentCategoryId); 20 | 21 | // @Caching(evict = { 22 | // @CacheEvict(cacheNames = "ItemCategory", key = "#p0"), 23 | // @CacheEvict(cacheNames = "ItemCategoryAll", allEntries = true) 24 | // }) 25 | int delete(Long id); 26 | 27 | //@Cacheable(cacheNames = "ItemCategory", key = "#p0") 28 | ItemCategory findById(Long id); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/ItemImgMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.itemImg.ItemImg; 4 | import java.util.List; 5 | 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.springframework.cache.annotation.Cacheable; 8 | 9 | @Mapper 10 | public interface ItemImgMapper { 11 | 12 | int save(ItemImg itemImg); 13 | 14 | @Cacheable(cacheNames = "ItemImg", key = "#p0") 15 | List findImagesByItemId(Long itemId); 16 | 17 | int delete(Long id); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/ItemMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.brand.Brand; 4 | import com.flab.fkream.item.Item; 5 | import java.util.List; 6 | 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.springframework.cache.annotation.CacheEvict; 9 | import org.springframework.cache.annotation.Cacheable; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @Mapper 13 | public interface ItemMapper { 14 | 15 | int save(Item item); 16 | 17 | @Cacheable(cacheNames = "Item", key = "#p0") 18 | Item findOne(Long id); 19 | 20 | List findAll(); 21 | 22 | int update(Item itemInfo); 23 | 24 | int delete(Long id); 25 | 26 | List findByBrand(Brand brand); 27 | 28 | List findByPrefix(String content); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/ItemSizePriceMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.itemSizePrice.ItemSizePrice; 4 | import java.util.List; 5 | 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | @Mapper 10 | public interface ItemSizePriceMapper { 11 | int save(ItemSizePrice itemSizePrice); 12 | 13 | ItemSizePrice findOne(Long id); 14 | 15 | @Transactional(readOnly = true) 16 | List findAllByItemId(Long itemId); 17 | @Transactional(readOnly = true) 18 | ItemSizePrice findByItemIdAndSize(Long itemId, String size); 19 | 20 | int update(ItemSizePrice itemSizePrice); 21 | 22 | int delete(Long id); 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/ListingMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.search.dbSearch.SearchItemDto; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.cache.annotation.Cacheable; 7 | 8 | @Mapper 9 | public interface ListingMapper { 10 | 11 | 12 | @Cacheable(cacheNames = "Listing", key = "#root.methodName" ) 13 | List generateRecommendedItemsForMen(int month); 14 | 15 | @Cacheable(cacheNames = "Listing", key = "#root.methodName") 16 | List generateRecommendedItemsForWomen(int month); 17 | 18 | 19 | @Cacheable(cacheNames = "Listing", key = "#root.methodName") 20 | List generateItemsBelowReleasedPrice(int month); 21 | 22 | 23 | @Cacheable(cacheNames = "Listing", key = "#root.methodName") 24 | List generatePopularLuxuryItems(int month); 25 | 26 | 27 | @Cacheable(cacheNames = "Listing", key = "#root.methodName") 28 | List generateMostPopularItems(); 29 | 30 | 31 | @Cacheable(cacheNames = "Listing", key = "#root.methodName") 32 | List generatePopularSneakers(int month); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/ManagerMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.manager.Manager; 4 | import java.util.List; 5 | 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | @Mapper 9 | public interface ManagerMapper { 10 | Long save(Manager manager); 11 | 12 | Manager findOne(Long id); 13 | 14 | List findAll(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/MyItemMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.myItems.MyItem; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface MyItemMapper { 9 | 10 | int save(MyItem myItem); 11 | 12 | MyItem findOne(Long id); 13 | 14 | List findAllByUserId(Long userId); 15 | 16 | int update(MyItem myItem); 17 | 18 | int delete(Long id); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/NotificationMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | 4 | import com.flab.fkream.notification.Notification; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface NotificationMapper { 9 | 10 | void save(Notification notification); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/PaymentCardMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.paymentCard.PaymentCard; 4 | import java.util.List; 5 | import org.apache.ibatis.annotations.Mapper; 6 | 7 | @Mapper 8 | public interface PaymentCardMapper { 9 | 10 | int save(PaymentCard paymentCard); 11 | 12 | List findByUserId(Long id); 13 | 14 | PaymentCard findById(Long id); 15 | 16 | int delete(Long id); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/SalesAccountMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.salesAccount.SalesAccount; 4 | import java.util.List; 5 | 6 | import org.apache.ibatis.annotations.Mapper; 7 | 8 | @Mapper 9 | public interface SalesAccountMapper { 10 | 11 | int save(SalesAccount salesAccount); 12 | 13 | SalesAccount findByUserId(Long userId); 14 | 15 | List findAll(); 16 | 17 | int update(SalesAccount salesAccount); 18 | 19 | int deleteByUserId(Long userId); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/SearchMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.AutoComplete.AutoCompletedItemDto; 4 | import com.flab.fkream.search.SearchCriteria; 5 | import com.flab.fkream.search.dbSearch.SearchItemDto; 6 | import java.util.List; 7 | import org.apache.ibatis.annotations.Mapper; 8 | import org.apache.ibatis.annotations.Param; 9 | 10 | @Mapper 11 | public interface SearchMapper { 12 | 13 | 14 | List searchAll(); 15 | 16 | List searchByCriteria(SearchCriteria searchCriteria); 17 | 18 | int findAllCount(); 19 | 20 | int findCountByCriteria(SearchCriteria searchCriteria); 21 | 22 | // List autoComplete(@Param("results") List results); 23 | 24 | List autoComplete(@Param("results") String results); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.mapper; 2 | 3 | import com.flab.fkream.login.LoginForm; 4 | import com.flab.fkream.user.User; 5 | import org.apache.ibatis.annotations.*; 6 | 7 | @Mapper 8 | public interface UserMapper { 9 | 10 | void save(User user); 11 | 12 | User findByEmail(String email); 13 | 14 | User findOne(Long id); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/myItems/MyItem.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.myItems; 2 | 3 | import javax.validation.constraints.Min; 4 | import javax.validation.constraints.NotNull; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | @Getter 13 | @ToString 14 | @EqualsAndHashCode(of = "id") 15 | @Builder 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class MyItem { 19 | 20 | private Long id; 21 | @NotNull 22 | private Long userId; 23 | @NotNull 24 | private Long itemSizePriceId; 25 | @Min(value = 30000, message = "구매가는 적어도 30,000 이상이어야 합니다.") 26 | private int purchasePrice; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/myItems/MyItemService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.myItems; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.itemSizePrice.ItemSizePrice; 5 | import com.flab.fkream.mapper.ItemSizePriceMapper; 6 | import com.flab.fkream.mapper.MyItemMapper; 7 | import com.flab.fkream.mapper.UserMapper; 8 | import java.util.List; 9 | import java.util.Optional; 10 | import lombok.RequiredArgsConstructor; 11 | import lombok.extern.log4j.Log4j2; 12 | import org.apache.ibatis.javassist.NotFoundException; 13 | import org.springframework.stereotype.Service; 14 | 15 | @Service 16 | @Log4j2 17 | @RequiredArgsConstructor 18 | public class MyItemService { 19 | 20 | private final UserMapper userMapper; 21 | private final ItemSizePriceMapper itemSizePriceMapper; 22 | private final MyItemMapper myItemMapper; 23 | 24 | public int save(MyItem myItemInfo) throws NotFoundException { 25 | ItemSizePrice itemSizePrice = Optional.ofNullable( 26 | itemSizePriceMapper.findOne(myItemInfo.getItemSizePriceId()) 27 | ).orElseThrow(() -> new NotFoundException("해당 아이템사이즈가격을 찾을 수 없습니다.")); 28 | 29 | return myItemMapper.save(myItemInfo); 30 | } 31 | 32 | public MyItem findOne(Long myItemId) { 33 | MyItem myItem = myItemMapper.findOne(myItemId); 34 | if (myItem == null) { 35 | throw new NoDataFoundException(); 36 | } 37 | return myItem; 38 | } 39 | 40 | public List findAllByUserId(Long userId) { 41 | return myItemMapper.findAllByUserId(userId); 42 | } 43 | 44 | public void update(MyItem myItem) throws NotFoundException { 45 | ItemSizePrice itemSizePrice = Optional.ofNullable( 46 | itemSizePriceMapper.findOne(myItem.getItemSizePriceId()) 47 | ).orElseThrow(() -> new NotFoundException("해당 아이템사이즈가격을 찾을 수 없습니다.")); 48 | myItemMapper.update(myItem); 49 | } 50 | 51 | public void delete(Long id) { 52 | myItemMapper.delete(id); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/notification/Notification.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.notification; 2 | 3 | import com.flab.fkream.interestedItem.InterestedItem; 4 | import com.flab.fkream.user.User; 5 | import lombok.Builder; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.Getter; 8 | import lombok.ToString; 9 | 10 | import java.time.LocalDateTime; 11 | 12 | @Getter 13 | @Builder 14 | @EqualsAndHashCode(of = "id") 15 | @ToString 16 | public class Notification { 17 | private Long id; 18 | private final User user; 19 | private final InterestedItem interestedItem; 20 | private final NotificationType notificationType; 21 | private final LocalDateTime createdAt; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/notification/NotificationController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.notification; 2 | 3 | import lombok.RequiredArgsConstructor; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | @RequestMapping("/notifications") 9 | @RequiredArgsConstructor 10 | public class NotificationController { 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/notification/NotificationService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.notification; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | @Service 6 | public class NotificationService { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/notification/NotificationType.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.notification; 2 | 3 | public enum NotificationType { 4 | CHANGED_PRICE_OF_INTERESTED_ITEM, UPDATE_STATE_OF_ITEM 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/paymentCard/PaymentCard.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.paymentCard; 2 | 3 | import com.flab.fkream.error.exception.NoCardPasswordException; 4 | import com.flab.fkream.user.User; 5 | import com.flab.fkream.utils.SHA256Util; 6 | import javax.validation.constraints.NotEmpty; 7 | import javax.validation.constraints.NotNull; 8 | import javax.validation.constraints.Pattern; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Builder; 11 | import lombok.EqualsAndHashCode; 12 | import lombok.Getter; 13 | import lombok.NoArgsConstructor; 14 | import lombok.ToString; 15 | 16 | import java.time.LocalDate; 17 | import java.time.LocalDateTime; 18 | 19 | @Getter 20 | @Builder 21 | @EqualsAndHashCode(of = "id") 22 | @AllArgsConstructor 23 | @NoArgsConstructor 24 | @ToString 25 | public class PaymentCard { 26 | 27 | private Long id; 28 | @NotNull 29 | private Long userId; 30 | @NotEmpty 31 | private String cardCompany; 32 | @NotEmpty 33 | @Pattern(regexp = "^\\d{16}$", message = "Invalid credit card number") 34 | private String cardNumber; 35 | @NotNull 36 | @Pattern(regexp = "^(0[1-9]|1[0-2])/[0-9]{2}$", message = "Invalid expiration date") 37 | private String expiration; 38 | @NotEmpty 39 | private String cardPw; 40 | private LocalDateTime createdAt; 41 | 42 | public void setCreatedAtToNow() { 43 | this.createdAt = LocalDateTime.now(); 44 | } 45 | 46 | public void encryptPassword() { 47 | if (cardPw == null || cardPw.isEmpty()) { 48 | throw new NoCardPasswordException(); 49 | } 50 | cardPw = SHA256Util.encrypt(cardPw); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/paymentCard/PaymentCardController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.paymentCard; 2 | 3 | import com.flab.fkream.error.exception.NotOwnedDataException; 4 | import com.flab.fkream.salesAccount.SalesAccount; 5 | import com.flab.fkream.utils.HttpRequestUtils; 6 | import com.flab.fkream.utils.SessionUtil; 7 | import com.github.pagehelper.PageHelper; 8 | import com.github.pagehelper.PageInfo; 9 | import java.util.List; 10 | import javax.servlet.http.HttpSession; 11 | import javax.validation.Valid; 12 | import lombok.NonNull; 13 | import lombok.RequiredArgsConstructor; 14 | import org.springframework.http.HttpStatus; 15 | import org.springframework.web.bind.annotation.DeleteMapping; 16 | import org.springframework.web.bind.annotation.GetMapping; 17 | import org.springframework.web.bind.annotation.PatchMapping; 18 | import org.springframework.web.bind.annotation.PathVariable; 19 | import org.springframework.web.bind.annotation.PostMapping; 20 | import org.springframework.web.bind.annotation.RequestBody; 21 | import org.springframework.web.bind.annotation.RequestMapping; 22 | import org.springframework.web.bind.annotation.RequestParam; 23 | import org.springframework.web.bind.annotation.ResponseStatus; 24 | import org.springframework.web.bind.annotation.RestController; 25 | import org.springframework.web.server.ResponseStatusException; 26 | 27 | @RestController 28 | @RequiredArgsConstructor 29 | @RequestMapping("/payment-cards") 30 | public class PaymentCardController { 31 | 32 | private final PaymentCardService paymentCardService; 33 | 34 | @PostMapping("") 35 | @ResponseStatus(HttpStatus.CREATED) 36 | public void save(@Valid @RequestBody @NonNull PaymentCard paymentCard) { 37 | paymentCardService.save(paymentCard); 38 | } 39 | 40 | @GetMapping() 41 | public PageInfo findByUserId(@RequestParam int pageNum, @RequestParam(defaultValue = "10") int pageSize) { 42 | PageHelper.startPage(pageNum, pageSize); 43 | return PageInfo.of(paymentCardService.findByUserId()); 44 | } 45 | 46 | @GetMapping("/{id}") 47 | public PaymentCard findOne(@PathVariable Long id) { 48 | PaymentCard paymentCard = paymentCardService.findById(id); 49 | if (paymentCard.getUserId() == SessionUtil.getLoginUserId()) { 50 | return paymentCard; 51 | } 52 | throw new NotOwnedDataException(); 53 | } 54 | 55 | 56 | @DeleteMapping("/{id}") 57 | public void delete(@PathVariable Long id) { 58 | paymentCardService.deleteById(id); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/paymentCard/PaymentCardService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.paymentCard; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.PaymentCardMapper; 5 | import com.flab.fkream.utils.SessionUtil; 6 | import java.util.List; 7 | import lombok.RequiredArgsConstructor; 8 | import lombok.extern.log4j.Log4j2; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service 12 | @Log4j2 13 | @RequiredArgsConstructor 14 | public class PaymentCardService { 15 | 16 | private final PaymentCardMapper paymentCardMapper; 17 | 18 | public void save(PaymentCard paymentCard) { 19 | paymentCard.setCreatedAtToNow(); 20 | paymentCard.encryptPassword(); 21 | paymentCardMapper.save(paymentCard); 22 | } 23 | 24 | public List findByUserId() { 25 | Long userId = SessionUtil.getLoginUserId(); 26 | List paymentCards = paymentCardMapper.findByUserId(userId); 27 | return paymentCards; 28 | } 29 | 30 | public PaymentCard findById(Long id) { 31 | PaymentCard paymentCard = paymentCardMapper.findById(id); 32 | if (paymentCard == null) { 33 | throw new NoDataFoundException(); 34 | } 35 | return paymentCard; 36 | } 37 | 38 | public void deleteById(Long id) { 39 | findById(id); 40 | paymentCardMapper.delete(id); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/redis/RedisService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.redis; 2 | 3 | import com.flab.fkream.error.exception.GenerateAddressKeyException; 4 | import javax.annotation.Resource; 5 | import lombok.extern.log4j.Log4j2; 6 | import org.springframework.data.redis.core.ValueOperations; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | @Log4j2 11 | public class RedisService { 12 | 13 | @Resource(name = "redisValueOperations") 14 | private ValueOperations valueOps; 15 | 16 | public Long getAddressId() { 17 | Long addressId = 0L; 18 | try { 19 | addressId = valueOps.increment("spring:redis:getAddressId", 1L); 20 | } catch (Exception e) { 21 | log.error(e.toString()); 22 | throw new GenerateAddressKeyException(); 23 | } 24 | return addressId; 25 | } 26 | 27 | public void initAddressId() { 28 | valueOps.set("spring:redis:getAddressId", 0L); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/resolver/QueryStringArgResolver.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.resolver; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.PARAMETER) 10 | public @interface QueryStringArgResolver { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/resolver/QueryStringArgumentResolver.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.resolver; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import javax.servlet.http.HttpServletRequest; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.core.MethodParameter; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.web.bind.support.WebDataBinderFactory; 9 | import org.springframework.web.context.request.NativeWebRequest; 10 | import org.springframework.web.method.support.HandlerMethodArgumentResolver; 11 | import org.springframework.web.method.support.ModelAndViewContainer; 12 | 13 | @Component 14 | public class QueryStringArgumentResolver implements HandlerMethodArgumentResolver { 15 | 16 | @Autowired 17 | private ObjectMapper mapper; 18 | 19 | @Override 20 | public boolean supportsParameter(MethodParameter parameter) { 21 | return parameter.hasParameterAnnotation(QueryStringArgResolver.class); 22 | } 23 | 24 | @Override 25 | public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, 26 | NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { 27 | HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); 28 | String queryString = request.getQueryString(); 29 | if (queryString == null) { 30 | return null; 31 | } 32 | String json = qs2json(queryString); 33 | System.out.println("parameter.getParameterType() = " + parameter.getParameterType()); 34 | return mapper.readValue(json, parameter.getParameterType()); 35 | } 36 | 37 | private String qs2json(String a) { 38 | String res = "{\""; 39 | 40 | for (int i = 0; i < a.length(); i++) { 41 | if (a.charAt(i) == '=') { 42 | res += "\"" + ":" + "\""; 43 | } else if (a.charAt(i) == '&') { 44 | res += "\"" + "," + "\""; 45 | } else { 46 | res += a.charAt(i); 47 | } 48 | } 49 | res += "\"" + "}"; 50 | return res; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/salesAccount/SalesAccount.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.salesAccount; 2 | 3 | 4 | import javax.validation.constraints.NotNull; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.ToString; 11 | 12 | import java.time.LocalDateTime; 13 | 14 | @Getter 15 | @Builder 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | @EqualsAndHashCode(of = "id") 19 | @ToString 20 | public class SalesAccount { 21 | 22 | private Long id; 23 | @NotNull 24 | private Long userId; 25 | @NotNull 26 | private String bankName; 27 | @NotNull 28 | private String accountNumber; 29 | @NotNull 30 | private String accountHolder; 31 | private LocalDateTime createdAt; 32 | 33 | public void setCreatedAtToNow() { 34 | this.createdAt = LocalDateTime.now(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/salesAccount/SalesAccountController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.salesAccount; 2 | 3 | import com.flab.fkream.error.exception.NotOwnedDataException; 4 | import com.flab.fkream.utils.SessionUtil; 5 | import javax.validation.Valid; 6 | import lombok.NonNull; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.web.bind.annotation.DeleteMapping; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.PatchMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | import org.springframework.web.bind.annotation.RequestBody; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.ResponseStatus; 16 | import org.springframework.web.bind.annotation.RestController; 17 | 18 | @RestController 19 | @RequiredArgsConstructor 20 | @RequestMapping("/sales-accounts") 21 | public class SalesAccountController { 22 | 23 | private final SalesAccountService salesAccountService; 24 | 25 | @PostMapping("") 26 | @ResponseStatus(HttpStatus.CREATED) 27 | public void save(@Valid @RequestBody @NonNull SalesAccount salesAccountInfo) { 28 | salesAccountService.save(salesAccountInfo); 29 | } 30 | 31 | 32 | @GetMapping("") 33 | @ResponseStatus(HttpStatus.OK) 34 | public SalesAccount findByUserId() { 35 | SalesAccount salesAccount = salesAccountService.findByUserId(); 36 | return salesAccount; 37 | } 38 | 39 | @PatchMapping("") 40 | @ResponseStatus(HttpStatus.OK) 41 | public void update(@RequestBody SalesAccount salesAccountInfo) { 42 | if (salesAccountInfo.getUserId() != SessionUtil.getLoginUserId()) { 43 | throw new NotOwnedDataException(); 44 | } 45 | salesAccountService.update(salesAccountInfo); 46 | } 47 | 48 | @DeleteMapping("") 49 | @ResponseStatus(HttpStatus.OK) 50 | public void delete() { 51 | salesAccountService.deleteById(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/salesAccount/SalesAccountService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.salesAccount; 2 | 3 | import com.flab.fkream.error.exception.NoDataFoundException; 4 | import com.flab.fkream.mapper.SalesAccountMapper; 5 | import com.flab.fkream.utils.SessionUtil; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.log4j.Log4j2; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | @Log4j2 12 | @RequiredArgsConstructor 13 | public class SalesAccountService { 14 | 15 | private final SalesAccountMapper salesAccountMapper; 16 | 17 | public void save(SalesAccount salesAccount) { 18 | salesAccount.setCreatedAtToNow(); 19 | SalesAccount existingAccount = salesAccountMapper.findByUserId(salesAccount.getUserId()); 20 | if (existingAccount != null) { 21 | return; 22 | } 23 | salesAccountMapper.save(salesAccount); 24 | } 25 | 26 | public SalesAccount findByUserId() { 27 | SalesAccount salesAccount = salesAccountMapper.findByUserId(SessionUtil.getLoginUserId()); 28 | if (salesAccount == null) { 29 | throw new NoDataFoundException(); 30 | } 31 | return salesAccount; 32 | } 33 | 34 | public void update(SalesAccount salesAccount) { 35 | salesAccountMapper.update(salesAccount); 36 | } 37 | 38 | public void deleteById() { 39 | salesAccountMapper.deleteByUserId(SessionUtil.getLoginUserId()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/SearchCriteria.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search; 2 | 3 | import com.flab.fkream.item.ItemGender; 4 | import java.io.Serializable; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @Builder 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class SearchCriteria implements Serializable { 15 | 16 | private String context; 17 | private ItemGender gender; 18 | private Long brandId; 19 | private String[] size; 20 | private Integer minPrice; 21 | private Integer maxPrice; 22 | private Long[] categoryId; 23 | private Long[] detailedCategoryId; 24 | private SortCriteria sort; 25 | private Object[] sortValue; 26 | 27 | private static final String BAD_REQUEST_CRITERIA = "필터 기준을 잘못 입력했습니다"; 28 | 29 | public void validatePrice() { 30 | if (minPrice != null && maxPrice != null) { 31 | if (minPrice<0 || maxPrice<0) { 32 | throw new IllegalArgumentException("최소, 최대 가격은 음수일 수 없습니다."); 33 | } 34 | if (minPrice > maxPrice) { 35 | throw new IllegalArgumentException("최소 가격이 최대 가격보다 클 수 없습니다."); 36 | } 37 | } 38 | if (minPrice == null ^ maxPrice == null) { 39 | throw new IllegalArgumentException("최소 가격과 최대 가격을 하나만 입력할 수 없습니다."); 40 | } 41 | } 42 | } 43 | /** 44 | * [RDBMS] 45 | * private String context; 46 | * private ItemGender gender; 47 | * private Long brandId; 48 | * private String size; 49 | * private Integer minPrice; 50 | * private Integer maxPrice; 51 | * private Long[] categoryId; 52 | * private SortCriteria sort; 53 | * 54 | * ########################################################## 55 | * 56 | * [Elastic Search] 57 | * private String context; 58 | * private ItemGender gender; 59 | * private Long brandId; 60 | * private String[] size; 61 | * private Integer minPrice; 62 | * private Integer maxPrice; 63 | * private Long[] categoryId; 64 | * private Long[] detailedCategoryId; 65 | * private SortCriteria sort; 66 | * private Object[] sortValue; 67 | */ -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/SearchService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search; 2 | 3 | import java.io.IOException; 4 | 5 | public interface SearchService { 6 | 7 | T search(SearchCriteria searchCriteria) throws IOException; 8 | 9 | int findCount(SearchCriteria searchCriteria) throws IOException; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/SortCriteria.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search; 2 | 3 | public enum SortCriteria { 4 | POPULAR, PREMIUM_DESC, PREMIUM_ASC, LOWEST_SELLING_PRICE, HIGHEST_PURCHASE_PRICE, RELEASE_DATE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/dbSearch/SearchController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.dbSearch; 2 | 3 | import com.flab.fkream.resolver.QueryStringArgResolver; 4 | import com.flab.fkream.search.SearchCriteria; 5 | import com.github.pagehelper.PageHelper; 6 | import com.github.pagehelper.PageInfo; 7 | import lombok.RequiredArgsConstructor; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/search") 15 | @RequiredArgsConstructor 16 | public class SearchController { 17 | 18 | private final SearchServiceImpl searchService; 19 | @GetMapping("") 20 | public PageInfo searchItem( 21 | @QueryStringArgResolver SearchCriteria criteria, @RequestParam int pageNum, @RequestParam(defaultValue = "10") int pageSize) { 22 | PageHelper.startPage(pageNum, pageSize); 23 | return PageInfo.of(searchService.search(criteria)); 24 | } 25 | 26 | @GetMapping("/count") 27 | public int searchItemCount(@RequestParam(required = false) SearchCriteria searchCriteria) { 28 | return searchService.findCount(searchCriteria); 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/dbSearch/SearchItemDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.dbSearch; 2 | 3 | import java.io.Serializable; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @Builder 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class SearchItemDto implements Serializable { 14 | 15 | private Long itemId; 16 | 17 | private String itemName; 18 | 19 | private Long brandId; 20 | 21 | private String brandName; 22 | 23 | private int price; 24 | 25 | private Long itemImgId; 26 | 27 | private String imgName; 28 | 29 | private String imgUrl; 30 | 31 | private String sortCriteria; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/dbSearch/SearchServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.dbSearch; 2 | 3 | import com.flab.fkream.itemCategory.ItemCategoryService; 4 | import com.flab.fkream.mapper.SearchMapper; 5 | import com.flab.fkream.search.SearchCriteria; 6 | import com.flab.fkream.search.SearchService; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import lombok.extern.log4j.Log4j2; 10 | import org.springframework.stereotype.Service; 11 | 12 | @Service 13 | @RequiredArgsConstructor 14 | @Log4j2 15 | public class SearchServiceImpl implements SearchService { 16 | 17 | private static final String CATEGORY_ERROR_MESSAGE = "잘못된 카테고리를 입력하셨습니다."; 18 | 19 | private final SearchMapper searchMapper; 20 | private final ItemCategoryService itemCategoryService; 21 | 22 | 23 | public List search(SearchCriteria searchCriteria) { 24 | if (searchCriteria == null) { 25 | return searchMapper.searchAll(); 26 | } 27 | validateCriteria(searchCriteria); 28 | return searchMapper.searchByCriteria(searchCriteria); 29 | } 30 | 31 | public int findCount(SearchCriteria searchCriteria) { 32 | if (searchCriteria == null) { 33 | return searchMapper.findAllCount(); 34 | } 35 | validateCriteria(searchCriteria); 36 | return searchMapper.findCountByCriteria(searchCriteria); 37 | } 38 | 39 | private void validateCriteria(SearchCriteria searchCriteria) { 40 | searchCriteria.validatePrice(); 41 | if (!itemCategoryService.isValidCategoryId(searchCriteria.getCategoryId())) { 42 | throw new IllegalArgumentException(CATEGORY_ERROR_MESSAGE); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/AbstractElasticsearchConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import org.elasticsearch.client.RestHighLevelClient; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; 6 | import org.springframework.data.elasticsearch.core.ElasticsearchOperations; 7 | import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; 8 | import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; 9 | 10 | public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport { 11 | 12 | @Bean 13 | public abstract RestHighLevelClient elasticsearchClient(); 14 | 15 | @Bean(name = {"elasticsearchOperations", "elasticsearchTemplate"}) 16 | public ElasticsearchOperations elasticsearchOperations( 17 | ElasticsearchConverter elasticsearchConverter, 18 | RestHighLevelClient elasticsearchClient) { 19 | 20 | ElasticsearchRestTemplate template = new ElasticsearchRestTemplate(elasticsearchClient, 21 | elasticsearchConverter); 22 | template.setRefreshPolicy(refreshPolicy()); 23 | 24 | return template; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/ElasticSearchConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import org.elasticsearch.client.RestHighLevelClient; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.data.elasticsearch.client.ClientConfiguration; 7 | import org.springframework.data.elasticsearch.client.RestClients; 8 | import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration; 9 | import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; 10 | 11 | @Configuration 12 | @EnableElasticsearchRepositories // elasticsearch repository 허용 13 | public class ElasticSearchConfig extends AbstractElasticsearchConfiguration { 14 | 15 | @Value("${spring.elasticsearch.uris}") 16 | private String server; 17 | 18 | @Value("${spring.elasticsearch.username}") 19 | private String username; 20 | 21 | @Value("${spring.elasticsearch.password}") 22 | private String password; 23 | 24 | @Override 25 | public RestHighLevelClient elasticsearchClient() { 26 | ClientConfiguration clientConfiguration = ClientConfiguration.builder() 27 | .connectedTo(server) 28 | .withBasicAuth(username, password) 29 | .build(); 30 | return RestClients.create(clientConfiguration).rest(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/ElasticSearchCriteria.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import com.flab.fkream.item.ItemGender; 4 | import com.flab.fkream.search.SortCriteria; 5 | import java.io.Serializable; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @Builder 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class ElasticSearchCriteria implements Serializable { 16 | 17 | private String context; 18 | private ItemGender gender; 19 | private Long brandId; 20 | private String[] size; 21 | private Integer minPrice; 22 | private Integer maxPrice; 23 | private Long[] categoryId; 24 | private Long[] detailedCategoryId; 25 | private SortCriteria sort; 26 | private Object[] sortValue; 27 | 28 | private static final String BAD_REQUEST_CRITERIA = "필터 기준을 잘못 입력했습니다"; 29 | 30 | public void validatePrice() { 31 | if (minPrice != null && maxPrice != null) { 32 | if (minPrice < 0 || maxPrice < 0) { 33 | throw new IllegalArgumentException("최소, 최대 가격은 음수일 수 없습니다."); 34 | } 35 | if (minPrice > maxPrice) { 36 | throw new IllegalArgumentException("최소 가격이 최대 가격보다 클 수 없습니다."); 37 | } 38 | } 39 | if (minPrice == null ^ maxPrice == null) { 40 | throw new IllegalArgumentException("최소 가격과 최대 가격을 하나만 입력할 수 없습니다."); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/ItemDocumentsDto.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import java.util.List; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | @Data 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | @Builder 13 | public class ItemDocumentsDto { 14 | 15 | private List itemDocumentList; 16 | private Object[] sortValues; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/ItemSearchRepository.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import com.flab.fkream.item.Item; 4 | import java.util.List; 5 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 6 | 7 | public interface ItemSearchRepository extends ElasticsearchRepository { 8 | 9 | List findTop5ByItemNameStartingWithOrderByDealCount(String itemName); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/PremiumRateBySize.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @AllArgsConstructor 11 | @NoArgsConstructor 12 | public class PremiumRateBySize { 13 | 14 | private String size; 15 | private int premiumRate; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/SearchDocument.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import java.time.LocalDateTime; 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Getter; 8 | import lombok.NoArgsConstructor; 9 | import org.springframework.data.annotation.Id; 10 | import org.springframework.data.elasticsearch.annotations.DateFormat; 11 | import org.springframework.data.elasticsearch.annotations.Document; 12 | import org.springframework.data.elasticsearch.annotations.Field; 13 | import org.springframework.data.elasticsearch.annotations.FieldType; 14 | 15 | @Builder 16 | @Getter 17 | @AllArgsConstructor 18 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 19 | @Document(indexName = "ranking") 20 | public class SearchDocument { 21 | 22 | @Id 23 | private Long id; 24 | 25 | @Field(type = FieldType.Keyword) 26 | private String searchWord; 27 | 28 | @Field(type = FieldType.Integer) 29 | private Integer searchCount; 30 | 31 | @Field(type = FieldType.Date, format = {DateFormat.date_hour_minute_second_millis, 32 | DateFormat.epoch_millis}) 33 | private LocalDateTime createdAt; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/SearchRankingRepository.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.List; 5 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; 6 | 7 | public interface SearchRankingRepository extends ElasticsearchRepository { 8 | 9 | List findTop10ByCreatedAtOrderBySearchCountDesc(LocalDateTime createdAt); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/search/elasticsearch/SearchRankingService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search.elasticsearch; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.temporal.ChronoUnit; 5 | import java.util.List; 6 | import lombok.RequiredArgsConstructor; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | @RequiredArgsConstructor 11 | public class SearchRankingService { 12 | 13 | private final SearchRankingRepository searchRankingRepository; 14 | 15 | public List getSearchRanking() { 16 | LocalDateTime now = LocalDateTime.now(); 17 | if (now.getMinute() >= 5) { 18 | return searchRankingRepository.findTop10ByCreatedAtOrderBySearchCountDesc( 19 | now.truncatedTo( 20 | ChronoUnit.HOURS)); 21 | } else { 22 | return searchRankingRepository.findTop10ByCreatedAtOrderBySearchCountDesc( 23 | now.minusHours(1).truncatedTo(ChronoUnit.HOURS)); 24 | } 25 | } 26 | 27 | /* 28 | public void saveSearchDocument(SearchDocument searchDocument) { 29 | searchRankingRepository.save(searchDocument); 30 | } 31 | 32 | @Transactional 33 | public void saveAllSearchDocuments(List searchDocumentList) { 34 | searchRankingRepository.saveAll(searchDocumentList); 35 | } 36 | */ 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/AddressShardingConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | import javax.annotation.PostConstruct; 4 | import lombok.Setter; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | @ConfigurationProperties(prefix = "sharding") 10 | @Setter 11 | public class AddressShardingConfig { 12 | 13 | private ShardingProperty address; 14 | 15 | @PostConstruct 16 | public void init() { 17 | ShardingConfig.getShardingPropertyMap().put(ShardingTarget.ADDRESS, address); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/AllShardQuery.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target(ElementType.METHOD) 11 | public @interface AllShardQuery { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/MapperShardingAspect.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | 4 | import com.flab.fkream.address.Address; 5 | import com.flab.fkream.user.User; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import lombok.RequiredArgsConstructor; 9 | import org.aspectj.lang.ProceedingJoinPoint; 10 | import org.aspectj.lang.annotation.Around; 11 | import org.aspectj.lang.annotation.Aspect; 12 | import org.springframework.stereotype.Component; 13 | 14 | @Component 15 | @Aspect 16 | @RequiredArgsConstructor 17 | public class MapperShardingAspect { 18 | 19 | private final DataSourceRouter dataSourceRouter; 20 | 21 | @Around("@annotation(com.flab.fkream.sharding.Sharding) && @annotation(sharding) && args(shardKey,..)") 22 | public Object handler(ProceedingJoinPoint joinPoint, Sharding sharding, long shardKey) 23 | throws Throwable { 24 | UserHolder.setSharding(sharding.target(), shardKey); 25 | Object returnVal = joinPoint.proceed(); 26 | UserHolder.clearSharding(); 27 | return returnVal; 28 | } 29 | 30 | @Around("@annotation(com.flab.fkream.sharding.AllShardQuery)") 31 | public List handleAllShardQuery(ProceedingJoinPoint joinPoint) throws Throwable { 32 | int shardSize = dataSourceRouter.getShardSize(); 33 | List result = new ArrayList<>(); 34 | for (int i = 0; i < shardSize; i++) { 35 | UserHolder.setShardingWithShardNo(i); 36 | result.addAll((List) joinPoint.proceed()); 37 | } 38 | UserHolder.clearSharding(); 39 | return result; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/Sharding.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.METHOD) 10 | public @interface Sharding { 11 | 12 | ShardingTarget target(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/ShardingConfig.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | import lombok.Setter; 6 | 7 | @Setter 8 | public class ShardingConfig { 9 | 10 | private static Map shardingPropertyMap = new ConcurrentHashMap<>(); 11 | 12 | 13 | public static Map getShardingPropertyMap() { 14 | return shardingPropertyMap; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/ShardingDataSourceProperty.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | import java.util.List; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | import lombok.Setter; 8 | 9 | @Getter 10 | @Setter 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ShardingDataSourceProperty { 14 | 15 | private List shards; 16 | 17 | @Getter 18 | @Setter 19 | @AllArgsConstructor 20 | @NoArgsConstructor 21 | public static class Shard { 22 | 23 | private Property master; 24 | private Property slave; 25 | 26 | } 27 | 28 | @Getter 29 | @Setter 30 | @AllArgsConstructor 31 | @NoArgsConstructor 32 | public static class Property { 33 | 34 | private String url; 35 | private String username; 36 | private String password; 37 | private String name; 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/ShardingProperty.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | import java.util.List; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | import lombok.Setter; 8 | 9 | @Getter 10 | @Setter 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ShardingProperty { 14 | 15 | private ShardingStrategy strategy; 16 | private List rules; 17 | 18 | @Getter 19 | @Setter 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public static class ShardingRule { 23 | 24 | private int shardNo; 25 | private long rangeMin; 26 | private long rangeMax; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/ShardingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | public enum ShardingStrategy { 4 | RANGE, MODULAR 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/ShardingTarget.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | public enum ShardingTarget { 4 | ADDRESS 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/sharding/UserHolder.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | 4 | import lombok.Getter; 5 | import lombok.NoArgsConstructor; 6 | import lombok.Setter; 7 | 8 | public class UserHolder { 9 | 10 | private static final ThreadLocal userCotext = new ThreadLocal<>(); 11 | 12 | public static Context getUserContext() { 13 | if (userCotext.get() == null) { 14 | Context context = new Context(); 15 | context.setSharding(null); 16 | userCotext.set(context); 17 | return userCotext.get(); 18 | } 19 | return userCotext.get(); 20 | } 21 | 22 | public static void setSharding(ShardingTarget target, long shardKey) { 23 | getUserContext().setSharding(new Sharding(target, shardKey)); 24 | } 25 | 26 | public static void setShardingWithShardNo(int shardNo) { 27 | Sharding sharding = new Sharding(); 28 | sharding.setShardNo(shardNo); 29 | getUserContext().setSharding(sharding); 30 | } 31 | 32 | public static void clearSharding() { 33 | getUserContext().setSharding(null); 34 | } 35 | 36 | public static Sharding getSharding() { 37 | return getUserContext().getSharding(); 38 | } 39 | 40 | 41 | @Getter 42 | @Setter 43 | public static class Context { 44 | 45 | private Sharding sharding; 46 | } 47 | 48 | @Getter 49 | @Setter 50 | @NoArgsConstructor 51 | public static class Sharding { 52 | 53 | private ShardingTarget target; 54 | private long shardKey; 55 | private Integer shardNo; 56 | 57 | public Sharding(ShardingTarget target, long shardKey) { 58 | this.target = target; 59 | this.shardKey = shardKey; 60 | } 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/user/User.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.user; 2 | 3 | import javax.validation.constraints.AssertTrue; 4 | import lombok.*; 5 | 6 | import javax.validation.constraints.NotNull; 7 | import java.time.LocalDateTime; 8 | 9 | @Getter 10 | @Builder 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @EqualsAndHashCode(of = "id") 14 | @ToString 15 | public class User { 16 | 17 | private Long id; 18 | 19 | @NotNull(message = "이메일은 필수입니다.") 20 | private String email; 21 | @NotNull(message = "비밀번호는 필수입니다.") 22 | private String password; 23 | @AssertTrue(message = "동의는 필수입니다.") 24 | private boolean fourteenAgreement; 25 | @AssertTrue(message = "동의은 필수입니다.") 26 | private boolean adAgreement; 27 | @AssertTrue(message = "동의은 필수입니다.") 28 | private boolean personalAuthentication; 29 | @NotNull(message = "성별은 필수입니다.") 30 | private String gender; 31 | @NotNull(message = "전화번호는 필수입니다.") 32 | private String phoneNumber; 33 | private String profileName; 34 | @NotNull(message = "이름은 필수입니다.") 35 | private String name; 36 | private String profileImgName; 37 | private String profileImgUrl; 38 | private String profileImgOriginName; 39 | private LocalDateTime createdAt; 40 | private LocalDateTime modifiedAt; 41 | 42 | public void setPassword(String password) { 43 | this.password = password; 44 | } 45 | 46 | public void setCreatedAt(LocalDateTime createdAt) { 47 | this.createdAt = createdAt; 48 | } 49 | 50 | public void setModifiedAt(LocalDateTime modifiedAt) { 51 | this.modifiedAt = modifiedAt; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/user/UserController.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.user; 2 | 3 | import javax.validation.Valid; 4 | import lombok.RequiredArgsConstructor; 5 | import lombok.extern.log4j.Log4j2; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestBody; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | @RestController 14 | @RequestMapping("/users") 15 | @RequiredArgsConstructor 16 | @Log4j2 17 | public class UserController { 18 | 19 | private final UserService userService; 20 | 21 | @PostMapping("") 22 | public ResponseEntity signUp(@Valid @RequestBody User user) { 23 | userService.addUser(user); 24 | return new ResponseEntity(HttpStatus.CREATED); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/user/UserService.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.user; 2 | 3 | import com.flab.fkream.error.exception.DuplicatedEmailException; 4 | import com.flab.fkream.error.exception.LoginFailureException; 5 | import com.flab.fkream.error.exception.NoDataFoundException; 6 | import com.flab.fkream.login.LoginForm; 7 | import com.flab.fkream.mapper.UserMapper; 8 | import com.flab.fkream.utils.SHA256Util; 9 | import java.time.LocalDateTime; 10 | import java.util.concurrent.TimeUnit; 11 | import lombok.RequiredArgsConstructor; 12 | import lombok.extern.log4j.Log4j2; 13 | import org.redisson.api.RLock; 14 | import org.redisson.api.RedissonClient; 15 | import org.springframework.stereotype.Service; 16 | 17 | @Service 18 | @Log4j2 19 | @RequiredArgsConstructor 20 | public class UserService { 21 | 22 | private final UserMapper userMapper; 23 | private final RedissonClient redissonClient; 24 | 25 | 26 | public void addUser(User user) { 27 | String lockName = generateLockName(user.getEmail()); 28 | RLock rLock = redissonClient.getLock(lockName); 29 | try { 30 | if (!rLock.tryLock(0, TimeUnit.MILLISECONDS)) { 31 | throw new NoDataFoundException(); 32 | } 33 | isDuplicatedEmail(user.getEmail()); 34 | user.setPassword(SHA256Util.encrypt(user.getPassword())); 35 | user.setCreatedAt(LocalDateTime.now()); 36 | userMapper.save(user); 37 | } catch (InterruptedException e) { 38 | e.printStackTrace(); 39 | throw new RuntimeException(e); 40 | } finally { 41 | unlock(rLock); 42 | } 43 | } 44 | 45 | public User login(LoginForm loginForm) { 46 | loginForm.setPassword(SHA256Util.encrypt(loginForm.getPassword())); 47 | User user = userMapper.findByEmail(loginForm.getEmail()); 48 | if (user == null) { 49 | throw new LoginFailureException(); 50 | } 51 | if (user.getPassword().equals(loginForm.getPassword())) { 52 | return user; 53 | } 54 | throw new LoginFailureException(); 55 | } 56 | 57 | private String generateLockName(String email) { 58 | return this.getClass() + email; 59 | } 60 | 61 | private void isDuplicatedEmail(String email) { 62 | User user = userMapper.findByEmail(email); 63 | if (user != null) { 64 | throw new DuplicatedEmailException(); 65 | } 66 | } 67 | 68 | private void unlock(RLock rLock) { 69 | if (rLock != null && rLock.isLocked()) { 70 | rLock.unlock(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/utils/HttpRequestUtils.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.utils; 2 | 3 | import org.springframework.web.context.request.RequestContextHolder; 4 | import org.springframework.web.context.request.ServletRequestAttributes; 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | public class HttpRequestUtils { 8 | 9 | public static HttpServletRequest getRequest() { 10 | return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 11 | } 12 | 13 | public static String getIpAddress() { 14 | return (null != getRequest().getHeader("X-FORWARDED-FOR")) ? getRequest().getHeader("X-FORWARDED-FOR") : getRequest().getRemoteAddr(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/utils/SHA256Util.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.utils; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | 6 | public class SHA256Util { 7 | 8 | private static final String ENCRYPTION_TYPE ="SHA-256"; 9 | 10 | public static String encrypt(String context){ 11 | 12 | String SHA = null; 13 | 14 | try{ 15 | MessageDigest messageDigest = MessageDigest.getInstance(ENCRYPTION_TYPE); 16 | messageDigest.update(context.getBytes()); 17 | return bytesToHex(messageDigest.digest()); 18 | 19 | } catch (NoSuchAlgorithmException e) { 20 | throw new RuntimeException("암호화 에러",e); 21 | } 22 | } 23 | 24 | private static String bytesToHex(byte[] bytes){ 25 | StringBuilder builder = new StringBuilder(); 26 | for (byte b : bytes) { 27 | builder.append(String.format("%02x",b)); 28 | } 29 | return builder.toString(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/flab/fkream/utils/SessionUtil.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.utils; 2 | 3 | import javax.servlet.http.HttpSession; 4 | 5 | public class SessionUtil { 6 | 7 | private static final String LOGIN_USERS_ID = "LOGIN_USERS_ID"; 8 | private static final String LOGIN_MANAGER_ID = "LOGIN_MANAGER_ID"; 9 | 10 | //인스턴스화 방지 11 | private SessionUtil() { 12 | } 13 | 14 | public static void setLoginUserId(HttpSession session, Long id) { 15 | session.setAttribute(LOGIN_USERS_ID, id); 16 | } 17 | 18 | public static Long getLoginUserId(HttpSession session) { 19 | return (Long) session.getAttribute(LOGIN_USERS_ID); 20 | } 21 | 22 | 23 | public static Long getLoginUserId() { 24 | return (Long) HttpRequestUtils.getRequest().getSession().getAttribute(LOGIN_USERS_ID); 25 | } 26 | 27 | public static void logoutUser(HttpSession session) { 28 | session.removeAttribute(LOGIN_USERS_ID); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:log4jdbc:h2:mem:testdb 4 | username: sa 5 | password: 6 | driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy 7 | sql: 8 | init: 9 | mode: always 10 | schema-locations: 11 | - classpath:db_sql/testSchema.sql 12 | data-locations: 13 | - classpath:db_sql/data.sql 14 | 15 | pagehelper: 16 | helper-dialect: h2 -------------------------------------------------------------------------------- /src/main/resources/elastic/item-mapping.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": { 3 | "id": { 4 | "type": "long" 5 | }, 6 | "itemName": { 7 | "type": "text" 8 | }, 9 | "size": { 10 | "type": "keyword" 11 | }, 12 | "modelNumber": { 13 | "type": "text" 14 | }, 15 | "categoryId": { 16 | "type": "long" 17 | }, 18 | "detailedCategoryId": { 19 | "type": "long" 20 | }, 21 | "releaseDate": { 22 | "type": "date", 23 | "format": "yyyy-MM-dd||yyyy/MM/dd||epoch_millis" 24 | }, 25 | "releasedPrice": { 26 | "type": "integer" 27 | }, 28 | "gender": { 29 | "type": "keyword" 30 | }, 31 | "brand": { 32 | "type": "nested", 33 | "properties": { 34 | "id": { 35 | "type": "long" 36 | }, 37 | "brandName": { 38 | "type": "text" 39 | }, 40 | "isLuxury": { 41 | "type": "boolean" 42 | } 43 | } 44 | }, 45 | "dealCount": { 46 | "type": "integer" 47 | }, 48 | "premiumRateBySize": { 49 | "type": "object", 50 | "properties": { 51 | "key": { 52 | "type": "keyword" 53 | }, 54 | "value": { 55 | "type": "integer" 56 | } 57 | } 58 | }, 59 | "immediatePurchasePriceBySize": { 60 | "type": "nested", 61 | "properties": { 62 | "key": { 63 | "type": "keyword" 64 | }, 65 | "value": { 66 | "type": "integer" 67 | } 68 | } 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /src/main/resources/elastic/item-setting.json: -------------------------------------------------------------------------------- 1 | { 2 | "analysis": { 3 | "analyzer": { 4 | "korean": { 5 | "type": "nori" 6 | } 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/log4jdbc.log4j2.properties: -------------------------------------------------------------------------------- 1 | log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator 2 | log4jdbc.dump.sql.maxlinelength=0 3 | log4jdbc.auto.load.popular.drivers=false -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/AddressMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | insert into address (ID, USER_ID, NAME, PHONE_NUMBER, ZIPCODE, DETAIL1, DETAIL2, CREATED_AT, 22 | DEFAULT_ADDRESS) 23 | values (#{id} ,#{userId}, #{name}, #{phoneNumber}, #{zipcode}, #{detail1}, #{detail2}, 24 | #{createdAt}, #{defaultAddress}) 25 | 26 | 31 | 36 | 37 | update ADDRESS 38 | SET user_id = #{userId}, 39 | name = #{name}, 40 | phone_number = #{phoneNumber}, 41 | zipcode = #{zipcode}, 42 | detail1 = #{detail1}, 43 | detail2 = #{detail2}, 44 | default_address = #{defaultAddress}, 45 | created_at = #{createdAt} 46 | where id = #{id} 47 | 48 | 49 | delete 50 | from ADDRESS 51 | where id = #{id} 52 | 53 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/BrandMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | INSERT INTO BRAND(brand_name, is_luxury) 16 | VALUES (#{brandName}, #{luxury}) 17 | 18 | 19 | 24 | 25 | 29 | 30 | 35 | 36 | 37 | 38 | update BRAND 39 | set brand_name = #{brandName}, 40 | is_luxury = #{luxury} 41 | where id = #{id} 42 | 43 | 44 | 45 | delete 46 | from BRAND 47 | where id = #{id} 48 | 49 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/InterestedItem.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | INSERT INTO interested_item(user_id, item_size_price_id) 15 | VALUES (#{userId}, #{itemSizePriceId}) 16 | 17 | 18 | 23 | 24 | 31 | 32 | 33 | DELETE 34 | from INTERESTED_ITEM 35 | where USER_ID = #{userId} 36 | and ITEM_SIZE_PRICE_ID = #{itemSizePriceId} 37 | 38 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/ItemCategoryMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | insert into item_category (category_name, parent_category_id) 16 | values (#{name}, #{parentId}) 17 | 18 | 19 | 24 | 25 | 30 | 31 | 36 | 37 | 38 | delete 39 | from item_category 40 | where id = #{id} 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/ItemSizePriceMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | INSERT INTO item_size_price(item_id, size, lowest_selling_price, highest_purchase_price, 19 | modified_at) 20 | VALUES (#{itemId}, 21 | #{size}, 22 | #{lowestSellingPrice}, 23 | #{highestPurchasePrice}, 24 | #{modifiedAt}) 25 | 26 | 27 | 32 | 33 | 34 | 39 | 40 | 46 | 47 | 48 | update item_size_price 49 | set item_id = #{itemId}, 50 | size = #{size}, 51 | lowest_selling_price = #{lowestSellingPrice}, 52 | highest_purchase_price = #{highestPurchasePrice}, 53 | modified_at = #{modifiedAt} 54 | where id = #{id} 55 | 56 | 57 | 58 | delete 59 | from ITEM_SIZE_PRICE 60 | where id = #{id} 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/ManagerMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | insert into MANAGER (EMPLOYEE_NUMBER, PASSWORD, NAME, PHONE_NUMBER, AGREEMENT, CREATED_AT, MODIFIED_AT) 18 | VALUES ( #{employeeNumber} 19 | , #{password} 20 | , #{name} 21 | , #{phoneNumber} 22 | , #{agreement} 23 | , #{createdAt} 24 | , #{modifiedAt}); 25 | 26 | 27 | 32 | 33 | 37 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/MyItemMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | insert into OWNED_ITEMS (USER_ID, ITEM_SIZE_PRICE_ID, PURCHASE_PRICE) 15 | values (#{userId}, #{itemSizePriceId}, #{purchasePrice}) 16 | 17 | 18 | 23 | 24 | 29 | 30 | 31 | update OWNED_ITEMS 32 | set USER_ID = #{userId}, 33 | ITEM_SIZE_PRICE_ID = #{itemSizePriceId} 34 | where ID = #{id} 35 | 36 | 37 | 38 | delete 39 | from OWNED_ITEMS 40 | where ID = #{id} 41 | 42 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/NotifiactionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | insert into notification (USER_ID, INTERESTED_ITEM_ID, TYPE, CREATED_AT) 8 | values (#{user.id}, #{iterestedItem.id}, #{type}, #{createdAt}) 9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/PaymentCardMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | insert into payment_card (user_id, card_company, card_number, expiration, card_pw, created_at) 18 | values (#{userId}, #{cardCompany}, #{cardNumber}, #{expiration}, 19 | #{cardPw}, #{createdAt}) 20 | 21 | 22 | 27 | 28 | 33 | 34 | 35 | 36 | delete 37 | from payment_card 38 | where id = #{id} 39 | 40 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/SalesAccountMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | insert into sales_account (user_id, bank_name, account_number, account_holder, created_at) 19 | values (#{userId}, #{bankName}, #{accountNumber}, #{accountHolder}, #{createdAt}) 20 | 21 | 22 | 27 | 28 | 29 | 33 | 34 | 35 | UPDATE sales_account 36 | SET user_id = #{userId}, 37 | bank_name = #{bankName}, 38 | account_number = #{accountNumber}, 39 | account_holder = #{accountHolder}, 40 | created_at = #{createdAt} 41 | WHERE id = #{id} 42 | 43 | 44 | 45 | DELETE 46 | FROM sales_account 47 | WHERE USER_ID = #{userId} 48 | 49 | -------------------------------------------------------------------------------- /src/main/resources/mybatis/mapper/UsersMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | insert into users (EMAIL, PASSWORD, FOURTEEN_AGREEMENT, GENDER, AD_AGREEMENT, 28 | PERSONAL_AUTHENTICATION, PHONE_NUMBER, PROFILE_NAME, NAME, PROFILE_IMG_NAME, 29 | PROFILE_IMG_URL, PROFILE_IMG_ORIGIN_NAME, CREATED_AT, MODIFIED_AT) 30 | values ( #{email}, #{password}, #{fourteenAgreement}, #{gender}, #{adAgreement} 31 | , #{personalAuthentication}, #{phoneNumber} 32 | , #{profileName}, #{name}, #{profileImgName}, #{profileImgUrl}, #{profileImgOriginName} 33 | , #{createdAt}, #{modifiedAt}) 34 | 35 | 36 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/test/http/http_request.http: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/FkreamApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class FkreamApplicationTests { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/address/AddressServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.address; 2 | 3 | import static org.mockito.BDDMockito.*; 4 | 5 | import com.flab.fkream.mapper.AddressMapper; 6 | import java.util.List; 7 | import org.assertj.core.api.Assertions; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | @ExtendWith(MockitoExtension.class) 15 | class AddressServiceTest { 16 | 17 | @Mock 18 | AddressMapper addressMapper; 19 | 20 | @InjectMocks 21 | AddressService addressService; 22 | 23 | Address addressInfo = Address.builder() 24 | .userId(1L) 25 | .name("test") 26 | .phoneNumber("010") 27 | .zipcode("3") 28 | .detail1("ag") 29 | .detail2("ads") 30 | .build(); 31 | 32 | @Test 33 | void addAddress() { 34 | given(addressMapper.save(addressInfo)).willReturn(1); 35 | addressService.addAddress(addressInfo); 36 | then(addressMapper).should().save(addressInfo); 37 | } 38 | 39 | @Test 40 | void findOne() { 41 | given(addressMapper.findOne(1L)).willReturn(addressInfo); 42 | Assertions.assertThat(addressService.findOne(1L)).isEqualTo(addressInfo); 43 | } 44 | 45 | @Test 46 | void findByUserId() { 47 | given(addressMapper.findByUserId(1L)).willReturn(List.of(addressInfo)); 48 | Assertions.assertThat(addressService.findByUserId(1L)).hasSize(1); 49 | } 50 | 51 | @Test 52 | void update() { 53 | given(addressMapper.update(addressInfo)).willReturn(1); 54 | addressService.update(addressInfo); 55 | then(addressMapper).should().update(addressInfo); 56 | } 57 | 58 | @Test 59 | void delete() { 60 | given(addressMapper.delete(addressInfo.getId())).willReturn(1); 61 | addressService.delete(addressInfo.getId()); 62 | then(addressMapper).should().delete(addressInfo.getId()); 63 | } 64 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/brand/BrandMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.brand; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import com.flab.fkream.mapper.BrandMapper; 6 | import java.util.List; 7 | import org.junit.jupiter.api.Test; 8 | import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 11 | import org.springframework.test.context.ActiveProfiles; 12 | 13 | @MybatisTest 14 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 15 | @ActiveProfiles({"test"}) 16 | class BrandMapperTest { 17 | 18 | @Autowired 19 | BrandMapper brandMapper; 20 | 21 | Brand brandInfo = Brand.builder().brandName("샤넬").luxury(true).build(); 22 | 23 | @Test 24 | void 브랜드_추가() throws Exception { 25 | 26 | assertThat(brandMapper.save(brandInfo)).isEqualTo(1); 27 | } 28 | 29 | @Test 30 | void 브랜드_조회() throws Exception { 31 | brandMapper.save(brandInfo); 32 | assertThat(brandMapper.findOne(brandInfo.getId())).isEqualTo(brandInfo); 33 | } 34 | 35 | @Test 36 | void 브랜드_리스팅() { 37 | List all = brandMapper.findAll(); 38 | assertThat(all.size()).isEqualTo(201); 39 | } 40 | 41 | @Test 42 | void 브랜드_업데이트() { 43 | brandMapper.save(brandInfo); 44 | Long id = brandInfo.getId(); 45 | Brand BrandUpdated = Brand.builder().id(id).brandName("나이키").luxury(false).build(); 46 | brandMapper.update(BrandUpdated); 47 | assertThat(brandMapper.findOne(brandInfo.getId())).isEqualTo(BrandUpdated); 48 | } 49 | 50 | @Test 51 | void 브랜드_삭제() { 52 | brandMapper.save(brandInfo); 53 | brandMapper.delete(brandInfo.getId()); 54 | assertThat(brandMapper.findOne(brandInfo.getId())).isNull(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/brand/BrandServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.brand; 2 | 3 | import com.flab.fkream.mapper.BrandMapper; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.mockito.InjectMocks; 7 | import org.mockito.Mock; 8 | import org.mockito.junit.jupiter.MockitoExtension; 9 | 10 | import java.util.List; 11 | 12 | import static org.mockito.BDDMockito.*; 13 | 14 | @ExtendWith(MockitoExtension.class) 15 | class BrandServiceTest { 16 | 17 | @Mock 18 | BrandMapper brandMapper; 19 | @InjectMocks 20 | BrandService brandService; 21 | 22 | Brand brandInfo = Brand.builder().brandName("샤넬").luxury(true).build(); 23 | 24 | @Test 25 | void 브랜드_추가() throws Exception { 26 | 27 | given(brandMapper.save(brandInfo)).willReturn(1); 28 | brandService.addBrand(brandInfo); 29 | then(brandMapper).should().save(brandInfo); 30 | } 31 | 32 | @Test 33 | void 브랜드_조회() throws Exception { 34 | given(brandMapper.findOne(1L)).willReturn(brandInfo); 35 | brandService.findOne(1L); 36 | then(brandMapper).should().findOne(1L); 37 | } 38 | 39 | @Test 40 | void 브랜드_리스팅() { 41 | given(brandMapper.findAll()).willReturn(List.of(brandInfo)); 42 | brandService.findAll(); 43 | then(brandMapper).should().findAll(); 44 | } 45 | 46 | @Test 47 | void 브랜드_업데이트() { 48 | given(brandMapper.update(brandInfo)).willReturn(1); 49 | brandService.update(brandInfo); 50 | then(brandMapper).should().update(brandInfo); 51 | } 52 | 53 | @Test 54 | void 브랜드_삭제() { 55 | given(brandMapper.delete(1L)).willReturn(1); 56 | brandService.delete(1L); 57 | then(brandMapper).should().delete(1L); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/item/ItemServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.item; 2 | 3 | import com.flab.fkream.brand.Brand; 4 | import com.flab.fkream.brand.BrandService; 5 | import com.flab.fkream.AutoComplete.Trie; 6 | import com.flab.fkream.mapper.ItemMapper; 7 | import java.time.LocalDate; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | import java.util.List; 15 | 16 | import static org.mockito.BDDMockito.*; 17 | 18 | @ExtendWith(MockitoExtension.class) 19 | class ItemServiceTest { 20 | 21 | @Mock 22 | ItemMapper itemMapper; 23 | @Mock 24 | BrandService brandService; 25 | 26 | @Mock 27 | Trie trie; 28 | @InjectMocks 29 | ItemService itemService; 30 | 31 | Brand brand = Brand.builder().brandName("구찌").luxury(true).build(); 32 | 33 | Item itemInfo = 34 | Item.builder() 35 | .itemName("나이키 에어포스") 36 | .modelNumber("NK22035") 37 | .categoryId(1L) 38 | .detailedCategoryId(2L) 39 | .releaseDate(LocalDate.now()) 40 | .representativeColor("Black") 41 | .releasedPrice(10000) 42 | .brand(brand) 43 | .build(); 44 | 45 | @Test 46 | void 아이템_생성() { 47 | given(itemMapper.save(itemInfo)).willReturn(1); 48 | // doNothing().when(trie).insert(itemInfo.getItemName()); 49 | itemService.addItem(itemInfo); 50 | then(itemMapper).should().save(itemInfo); 51 | } 52 | 53 | @Test 54 | void 아이템_조회() { 55 | given(itemMapper.findOne(1L)).willReturn(itemInfo); 56 | given(brandService.findOne(brand.getId())).willReturn(brand); 57 | itemService.findOne(1L); 58 | then(itemMapper).should().findOne(1L); 59 | } 60 | 61 | @Test 62 | void 아이템_리스팅() { 63 | given(itemMapper.findAll()).willReturn(List.of(itemInfo)); 64 | given(brandService.findOne(brand.getId())).willReturn(brand); 65 | itemService.findAll(); 66 | then(itemMapper).should().findAll(); 67 | } 68 | 69 | @Test 70 | void 아이템_업데이트() { 71 | given(itemMapper.update(itemInfo)).willReturn(1); 72 | itemService.update(itemInfo); 73 | then(itemMapper).should().update(itemInfo); 74 | } 75 | 76 | @Test 77 | void 아이템_삭제() { 78 | given(itemMapper.delete(1L)).willReturn(1); 79 | itemService.delete(1L); 80 | then(itemMapper).should().delete(1L); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/itemCategory/ItemCategoryControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | import static org.mockito.BDDMockito.*; 5 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 6 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 7 | 8 | import com.fasterxml.jackson.core.JsonProcessingException; 9 | import com.fasterxml.jackson.databind.ObjectMapper; 10 | import com.flab.fkream.address.Address; 11 | import java.util.List; 12 | import org.junit.jupiter.api.Test; 13 | import org.mockito.BDDMockito; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 16 | import org.springframework.boot.test.mock.mockito.MockBean; 17 | import org.springframework.http.MediaType; 18 | import org.springframework.test.context.ActiveProfiles; 19 | import org.springframework.test.web.servlet.MockMvc; 20 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 21 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; 22 | 23 | @WebMvcTest(ItemCategoryController.class) 24 | @ActiveProfiles({"test"}) 25 | class ItemCategoryControllerTest { 26 | 27 | @MockBean 28 | ItemCategoryService itemCategoryService; 29 | 30 | @Autowired 31 | MockMvc mockMvc; 32 | 33 | ItemCategory itemCategory = ItemCategory.builder().name("신발") 34 | .build(); 35 | 36 | @Test 37 | void addCategory() throws Exception { 38 | doNothing().when(itemCategoryService).addCategory(itemCategory); 39 | mockMvc.perform(post("/categories").contentType(MediaType.APPLICATION_JSON).content(getContent(itemCategory))).andExpect(status().isOk()); 40 | } 41 | 42 | @Test 43 | void findAll() throws Exception { 44 | given(itemCategoryService.findAllCategory()).willReturn(List.of(new ItemCategoryDto(itemCategory,List.of()))); 45 | mockMvc.perform(get("/categories")).andExpect(status().isOk()); 46 | } 47 | 48 | @Test 49 | void delete() throws Exception { 50 | doNothing().when(itemCategoryService).delete(1L); 51 | mockMvc.perform(MockMvcRequestBuilders.delete("/categories/1")).andExpect(status().isOk()); 52 | } 53 | 54 | private String getContent(ItemCategory itemCategory) throws JsonProcessingException { 55 | return new ObjectMapper().writeValueAsString(itemCategory); 56 | } 57 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/itemCategory/ItemCategoryMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import com.flab.fkream.mapper.ItemCategoryMapper; 6 | import java.util.List; 7 | import org.junit.jupiter.api.Test; 8 | import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 11 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; 12 | import org.springframework.test.context.ActiveProfiles; 13 | 14 | @MybatisTest 15 | @AutoConfigureTestDatabase(replace = Replace.NONE) 16 | @ActiveProfiles({"test"}) 17 | class ItemCategoryMapperTest { 18 | 19 | @Autowired 20 | ItemCategoryMapper itemCategoryMapper; 21 | 22 | ItemCategory parentCategory = ItemCategory.builder().name("구두").build(); 23 | ItemCategory childCategory; 24 | 25 | 26 | @Test 27 | void add() { 28 | assertThat(itemCategoryMapper.save(parentCategory)).isEqualTo(1); 29 | } 30 | 31 | @Test 32 | void findParentCategory() { 33 | System.out.println("parentCategory = " + parentCategory); 34 | itemCategoryMapper.save(parentCategory); 35 | System.out.println("p = " + parentCategory); 36 | List parentCategory1 = itemCategoryMapper.findParentCategory(); 37 | System.out.println("parentCategory1 = " + parentCategory1); 38 | assertThat(itemCategoryMapper.findParentCategory()).contains(parentCategory); 39 | } 40 | 41 | @Test 42 | void findChildCategory() { 43 | itemCategoryMapper.save(parentCategory); 44 | childCategory = ItemCategory.builder().name("키높이구두").parentId(parentCategory.getId()) 45 | .build(); 46 | itemCategoryMapper.save(childCategory); 47 | assertThat(itemCategoryMapper.findChildCategory(parentCategory.getId())).contains( 48 | childCategory); 49 | } 50 | 51 | @Test 52 | void delete() { 53 | itemCategoryMapper.save(parentCategory); 54 | assertThat(itemCategoryMapper.delete(parentCategory.getId())).isEqualTo(1); 55 | } 56 | 57 | @Test 58 | void findById() { 59 | itemCategoryMapper.save(parentCategory); 60 | assertThat(itemCategoryMapper.findById(parentCategory.getId())).isEqualTo(parentCategory); 61 | } 62 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/itemCategory/ItemCategoryServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemCategory; 2 | 3 | import static org.assertj.core.api.Assertions.*; 4 | import static org.mockito.BDDMockito.*; 5 | 6 | import com.flab.fkream.mapper.ItemCategoryMapper; 7 | import java.util.List; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | @ExtendWith(MockitoExtension.class) 15 | class ItemCategoryServiceTest { 16 | 17 | @Mock 18 | ItemCategoryMapper itemCategoryMapper; 19 | 20 | @InjectMocks 21 | ItemCategoryService itemCategoryService; 22 | 23 | ItemCategory parentCategory = ItemCategory.builder().id(1L).name("신발").build(); 24 | ItemCategory parentCategory2 = ItemCategory.builder().id(3L).name("상의").build(); 25 | 26 | ItemCategory childCategory = ItemCategory.builder().id(2L).name("스니커즈").parentId(1L).build(); 27 | 28 | @Test 29 | void addCategory() { 30 | given(itemCategoryMapper.save(parentCategory)).willReturn(1); 31 | itemCategoryService.addCategory(parentCategory); 32 | then(itemCategoryMapper).should().save(parentCategory); 33 | } 34 | 35 | @Test 36 | void findById() { 37 | given(itemCategoryMapper.findById(1L)).willReturn(parentCategory); 38 | assertThat(itemCategoryService.findById(1L)).isEqualTo(parentCategory); 39 | } 40 | 41 | @Test 42 | void findAllCategory() { 43 | given(itemCategoryMapper.findParentCategory()).willReturn(List.of(parentCategory)); 44 | given(itemCategoryMapper.findChildCategory(1L)).willReturn(List.of(childCategory)); 45 | assertThat(itemCategoryService.findAllCategory()).hasSize(1); 46 | } 47 | 48 | @Test 49 | void delete() { 50 | given(itemCategoryMapper.delete(1L)).willReturn(1); 51 | itemCategoryService.delete(1L); 52 | then(itemCategoryMapper).should().delete(1L); 53 | } 54 | 55 | @Test 56 | void isValidCategoryId() { 57 | given(itemCategoryMapper.findById(1L)).willReturn(parentCategory); 58 | given(itemCategoryMapper.findById(2L)).willReturn(parentCategory2); 59 | given(itemCategoryMapper.findById(3L)).willReturn(childCategory); 60 | assertThat(itemCategoryService.isValidCategoryId(new Long[]{1L, 2L, 3L})).isFalse(); 61 | assertThat(itemCategoryService.isValidCategoryId(new Long[]{ 2L, 3L})).isTrue(); 62 | 63 | } 64 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/itemImg/ItemImgMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemImg; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import com.flab.fkream.brand.Brand; 6 | import com.flab.fkream.item.Item; 7 | import com.flab.fkream.mapper.ItemMapper; 8 | import com.flab.fkream.mapper.ItemImgMapper; 9 | import java.time.LocalDate; 10 | import org.junit.jupiter.api.BeforeEach; 11 | import org.junit.jupiter.api.Test; 12 | import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 15 | import org.springframework.test.context.ActiveProfiles; 16 | 17 | @MybatisTest 18 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 19 | @ActiveProfiles({"test"}) 20 | class ItemImgMapperTest { 21 | 22 | @Autowired 23 | ItemImgMapper itemImgMapper; 24 | @Autowired 25 | ItemMapper itemMapper; 26 | 27 | Item itemInfo = 28 | Item.builder() 29 | .itemName("나이키 에어포스") 30 | .modelNumber("NK22035") 31 | .categoryId(1L) 32 | .detailedCategoryId(2L) 33 | .releaseDate(LocalDate.now()) 34 | .representativeColor("Black") 35 | .releasedPrice(10000) 36 | .brand(new Brand()) 37 | .build(); 38 | 39 | ItemImg itemImgInfo = 40 | ItemImg.builder() 41 | .item(itemInfo) 42 | .imgUrl("test") 43 | .imgName("test") 44 | .originName("test_origin") 45 | //.isRepresentativeImg(true) 46 | .build(); 47 | 48 | @BeforeEach 49 | void setUp() { 50 | itemMapper.save(itemInfo); 51 | } 52 | 53 | @Test 54 | void save() { 55 | assertThat(itemImgMapper.save(itemImgInfo)).isEqualTo(1); 56 | } 57 | 58 | @Test 59 | void findImagesByItemId() { 60 | itemImgMapper.save(itemImgInfo); 61 | assertThat(itemImgMapper.findImagesByItemId(itemInfo.getId()).get(0)).isEqualTo( 62 | itemImgInfo); 63 | } 64 | 65 | @Test 66 | void delete() { 67 | itemImgMapper.save(itemImgInfo); 68 | itemImgMapper.delete(itemImgInfo.getId()); 69 | assertThat(itemImgMapper.findImagesByItemId(itemInfo.getId())).hasSize(0); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/itemImg/ItemImgServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemImg; 2 | 3 | import com.flab.fkream.brand.Brand; 4 | import com.flab.fkream.item.Item; 5 | import com.flab.fkream.mapper.ItemImgMapper; 6 | import java.time.LocalDate; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.extension.ExtendWith; 9 | import org.mockito.InjectMocks; 10 | import org.mockito.Mock; 11 | import org.mockito.junit.jupiter.MockitoExtension; 12 | 13 | import java.util.List; 14 | 15 | import static org.mockito.BDDMockito.*; 16 | 17 | @ExtendWith(MockitoExtension.class) 18 | class ItemImgServiceTest { 19 | 20 | @Mock 21 | ItemImgMapper itemImgMapper; 22 | @InjectMocks 23 | ItemImgService itemImgService; 24 | 25 | Brand brand = 26 | Brand.builder() 27 | .brandName("구찌") 28 | .luxury(true) 29 | .build(); 30 | 31 | Item itemInfo = 32 | Item.builder() 33 | .itemName("나이키 에어포스") 34 | .modelNumber("NK22035") 35 | .categoryId(1L) 36 | .detailedCategoryId(2L) 37 | .releaseDate(LocalDate.now()) 38 | .representativeColor("Black") 39 | .releasedPrice(10000) 40 | .brand(brand) 41 | .build(); 42 | 43 | ItemImg itemImgInfo = 44 | ItemImg.builder() 45 | .item(itemInfo) 46 | .imgUrl("test") 47 | .imgName("test") 48 | .originName("test_origin") 49 | //.isRepresentativeImg(true) 50 | .build(); 51 | 52 | @Test 53 | void addItemImg() { 54 | given(itemImgMapper.save(itemImgInfo)).willReturn(1); 55 | itemImgService.addItemImg(itemImgInfo); 56 | then(itemImgMapper).should().save(itemImgInfo); 57 | } 58 | 59 | @Test 60 | void findImagesByItemId() { 61 | given(itemImgMapper.findImagesByItemId(1L)).willReturn(List.of(itemImgInfo)); 62 | itemImgService.findImagesByItemId(1L); 63 | then(itemImgMapper).should().findImagesByItemId(1L); 64 | } 65 | 66 | @Test 67 | void delete() { 68 | given(itemImgMapper.delete(1L)).willReturn(1); 69 | itemImgService.delete(1L); 70 | then(itemImgMapper).should().delete(1L); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/itemSizePrice/ItemSizePriceServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.itemSizePrice; 2 | 3 | import static org.assertj.core.api.Assertions.*; 4 | import static org.mockito.BDDMockito.*; 5 | 6 | import com.flab.fkream.mapper.ItemSizePriceMapper; 7 | import java.util.List; 8 | import org.junit.jupiter.api.Test; 9 | import org.junit.jupiter.api.extension.ExtendWith; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.Mock; 12 | import org.mockito.junit.jupiter.MockitoExtension; 13 | 14 | @ExtendWith(MockitoExtension.class) 15 | class ItemSizePriceServiceTest { 16 | 17 | @Mock 18 | ItemSizePriceMapper itemSizePriceMapper; 19 | 20 | @InjectMocks 21 | ItemSizePriceService itemSizePriceService; 22 | 23 | private static final Long ID =1L; 24 | private static final Long ITEM_ID = 2L; 25 | private static final String SIZE = "260"; 26 | 27 | ItemSizePrice itemSizePriceInfo = ItemSizePrice.builder() 28 | .id(ID) 29 | .itemId(ITEM_ID) 30 | .size(SIZE) 31 | .build(); 32 | 33 | 34 | @Test 35 | void addItemSizePrice() { 36 | given(itemSizePriceMapper.save(itemSizePriceInfo)).willReturn(1); 37 | itemSizePriceService.addItemSizePrice(itemSizePriceInfo); 38 | then(itemSizePriceMapper).should().save(itemSizePriceInfo); 39 | } 40 | 41 | @Test 42 | void findOne() { 43 | given(itemSizePriceMapper.findOne(ID)).willReturn(itemSizePriceInfo); 44 | assertThat(itemSizePriceService.findOne(ID)).isEqualTo(itemSizePriceInfo); 45 | } 46 | 47 | @Test 48 | void findAllByItemId() { 49 | given(itemSizePriceMapper.findAllByItemId(ITEM_ID)).willReturn(List.of(itemSizePriceInfo)); 50 | assertThat(itemSizePriceService.findAllByItemId(ITEM_ID)).hasSize(1); 51 | } 52 | 53 | @Test 54 | void findByItemIdAndSize() { 55 | given(itemSizePriceMapper.findByItemIdAndSize(ITEM_ID,SIZE)).willReturn(itemSizePriceInfo); 56 | assertThat(itemSizePriceService.findByItemIdAndSize(ITEM_ID,SIZE)).isEqualTo(itemSizePriceInfo); 57 | } 58 | 59 | @Test 60 | void delete() { 61 | given(itemSizePriceMapper.delete(ID)).willReturn(1); 62 | itemSizePriceService.delete(ID); 63 | then(itemSizePriceMapper).should().delete(ID); 64 | } 65 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/paymentCard/PaymentCardMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.paymentCard; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import com.flab.fkream.mapper.PaymentCardMapper; 6 | import com.flab.fkream.user.User; 7 | import com.flab.fkream.mapper.UserMapper; 8 | import java.util.List; 9 | import org.junit.jupiter.api.BeforeEach; 10 | import org.junit.jupiter.api.Test; 11 | import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 14 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; 15 | import org.springframework.test.context.ActiveProfiles; 16 | 17 | @MybatisTest 18 | @AutoConfigureTestDatabase(replace = Replace.NONE) 19 | @ActiveProfiles({"test"}) 20 | class PaymentCardMapperTest { 21 | 22 | @Autowired 23 | PaymentCardMapper paymentCardMapper; 24 | 25 | @Autowired 26 | UserMapper userMapper; 27 | 28 | User user; 29 | 30 | PaymentCard paymentCard; 31 | 32 | @BeforeEach 33 | void setUp() { 34 | user = User.builder() 35 | .email("test1") 36 | .password("000") 37 | .gender("aa") 38 | .name("test") 39 | .adAgreement(true) 40 | .fourteenAgreement(true) 41 | .personalAuthentication(true) 42 | .phoneNumber("010") 43 | .build(); 44 | userMapper.save(user); 45 | paymentCard = PaymentCard.builder() 46 | .userId(user.getId()) 47 | .cardCompany("woori") 48 | .cardNumber("1111") 49 | .expiration("12/32") 50 | .cardPw("1234") 51 | .build(); 52 | } 53 | 54 | @Test 55 | void save() { 56 | assertThat(paymentCardMapper.save(paymentCard)).isEqualTo(1); 57 | } 58 | 59 | @Test 60 | void findByUserId() { 61 | paymentCardMapper.save(paymentCard); 62 | List paymentCards = paymentCardMapper.findByUserId(user.getId()); 63 | assertThat(paymentCards).contains(paymentCard); 64 | } 65 | 66 | @Test 67 | void findOne() { 68 | paymentCardMapper.save(paymentCard); 69 | assertThat(paymentCardMapper.findById(paymentCard.getId())).isEqualTo(paymentCard); 70 | } 71 | 72 | @Test 73 | void delete() { 74 | paymentCardMapper.save(paymentCard); 75 | assertThat(paymentCardMapper.delete(paymentCard.getId())).isEqualTo(1); 76 | } 77 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/redis/RedisServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.redis; 2 | 3 | import static org.assertj.core.api.Assertions.*; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | import java.util.concurrent.Callable; 10 | import java.util.concurrent.CountDownLatch; 11 | import java.util.concurrent.ExecutionException; 12 | import java.util.concurrent.ExecutorService; 13 | import java.util.concurrent.Executors; 14 | import java.util.concurrent.Future; 15 | import org.assertj.core.api.Assertions; 16 | import org.junit.jupiter.api.Test; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.boot.test.context.SpringBootTest; 19 | 20 | @SpringBootTest 21 | class RedisServiceTest { 22 | 23 | @Autowired 24 | private RedisService redisService; 25 | 26 | @Test 27 | void getAddressId() throws InterruptedException, ExecutionException { 28 | 29 | int threadCount = 10; 30 | Set results = new HashSet<>(); 31 | 32 | ExecutorService executorService = Executors.newFixedThreadPool(threadCount); 33 | List> futures = new ArrayList<>(); 34 | 35 | redisService.initAddressId(); 36 | 37 | for (int i = 0; i < threadCount; i++) { 38 | Callable callable = () -> { 39 | Long addressId = redisService.getAddressId(); 40 | return addressId; 41 | }; 42 | futures.add(executorService.submit(callable)); 43 | } 44 | executorService.shutdown(); 45 | for (Future future : futures) { 46 | results.add(future.get()); 47 | } 48 | 49 | assertThat(results.size()).isEqualTo(threadCount); 50 | assertThat(redisService.getAddressId()).isEqualTo(Integer.toUnsignedLong(threadCount + 1)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/search/TrieTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.search; 2 | 3 | import static org.assertj.core.api.Assertions.*; 4 | import static org.junit.jupiter.api.Assertions.*; 5 | 6 | import java.util.List; 7 | import org.assertj.core.api.Assertions; 8 | import org.junit.jupiter.api.Test; 9 | 10 | class TrieTest { 11 | 12 | // Trie trie = new Trie(); 13 | // 14 | // @Test 15 | // void search() { 16 | // trie.insert("사과"); 17 | // trie.insert("바나나"); 18 | // trie.insert("체리"); 19 | // trie.insert("두리안"); 20 | // 21 | // trie.insert("사과원"); 22 | // trie.insert("바나나원"); 23 | // trie.insert("체리원"); 24 | // trie.insert("두리안원"); 25 | // 26 | // trie.insert("사과투"); 27 | // trie.insert("바나나투"); 28 | // trie.insert("체리투"); 29 | // trie.insert("두리안투"); 30 | // 31 | // trie.insert("사과원투"); 32 | // trie.insert("사과원쓰리"); 33 | // trie.insert("사과원포"); 34 | // trie.insert("사과원투수"); 35 | // trie.insert("사과투포"); 36 | // trie.insert("사과투쓰리"); 37 | // trie.insert("사과투포파이브"); 38 | // 39 | // assertThat(trie.search("사과원")).contains("사과원투수").hasSize(5); 40 | // } 41 | } -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/sharding/ShardingTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.sharding; 2 | 3 | import com.flab.fkream.address.Address; 4 | import com.flab.fkream.address.AddressRepository; 5 | import java.sql.Connection; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.boot.test.mock.mockito.SpyBean; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | @SpringBootTest 13 | public class ShardingTest { 14 | 15 | @SpyBean 16 | DataSourceRouter shardingDataSource; 17 | @Autowired 18 | AddressRepository addressRepository; 19 | 20 | 21 | @Test 22 | @Transactional 23 | void shardingTest() { 24 | Long id1 = 20L; 25 | Long id2 = 120L; 26 | addressRepository.addAddress(id1, Address.builder().id(id1).name("testAddress1").build()); 27 | addressRepository.addAddress(id2, Address.builder().id(id2).name("testAddress2").build()); 28 | 29 | 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/flab/fkream/user/UserMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.flab.fkream.user; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import com.flab.fkream.mapper.UserMapper; 6 | import org.junit.jupiter.api.Test; 7 | import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; 10 | import org.springframework.test.context.ActiveProfiles; 11 | 12 | @MybatisTest 13 | @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) 14 | @ActiveProfiles({"test"}) 15 | class UserMapperTest { 16 | 17 | @Autowired 18 | UserMapper userMapper; 19 | 20 | User user = User.builder() 21 | .email("test1") 22 | .password("000") 23 | .gender("aa") 24 | .name("test") 25 | .adAgreement(true) 26 | .fourteenAgreement(true) 27 | .personalAuthentication(true) 28 | .phoneNumber("010") 29 | .build(); 30 | 31 | @Test 32 | void save() { 33 | userMapper.save(user); 34 | assertThat(user.getId()).isNotNull(); 35 | } 36 | 37 | @Test 38 | void findByEmail() { 39 | userMapper.save(user); 40 | User userFound = userMapper.findByEmail(user.getEmail()); 41 | assertThat(user).isEqualTo(userFound); 42 | } 43 | } --------------------------------------------------------------------------------