├── README.md ├── README ├── image-1.png ├── image.png ├── 남규.md ├── 상현.assets │ └── image-20230413174438384.png ├── 상현.md ├── 송빈.md ├── 애림.md ├── 현아.md └── 홍민.md ├── back-server ├── .gitignore ├── BackendSever.md ├── Dockerfile ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── server │ │ └── back │ │ ├── BackApplication.java │ │ ├── common │ │ ├── code │ │ │ ├── commonCode │ │ │ │ ├── AssetColorType.java │ │ │ │ ├── AssetLevelType.java │ │ │ │ ├── DealType.java │ │ │ │ ├── GotchaLevel.java │ │ │ │ ├── IsAuctioned.java │ │ │ │ ├── IsAuthor.java │ │ │ │ ├── IsCompleted.java │ │ │ │ ├── IsDeleted.java │ │ │ │ ├── IsInRespository.java │ │ │ │ ├── IsUsed.java │ │ │ │ ├── Role.java │ │ │ │ ├── TypeGroup.java │ │ │ │ └── TypeModel.java │ │ │ ├── controller │ │ │ │ └── CommonCodeController.java │ │ │ └── dto │ │ │ │ ├── ResultDto.java │ │ │ │ └── ResultEnum.java │ │ ├── entity │ │ │ ├── CommonEntity.java │ │ │ └── DealEntity.java │ │ ├── repository │ │ │ └── DealRepository.java │ │ └── service │ │ │ ├── AuthService.java │ │ │ ├── AuthTokenProvider.java │ │ │ ├── RedisService.java │ │ │ └── SchedulerService.java │ │ ├── config │ │ ├── CorsConfig.java │ │ ├── JwtExceptionFilter.java │ │ ├── JwtFilter.java │ │ ├── JwtSecurityConfig.java │ │ ├── RedisRepositoryConfig.java │ │ └── SwaggerConfig.java │ │ ├── domain │ │ ├── admin │ │ │ ├── controller │ │ │ │ ├── AdminAssetController.java │ │ │ │ ├── AdminDealController.java │ │ │ │ ├── AdminMarketController.java │ │ │ │ └── AdminUserController.java │ │ │ ├── dto │ │ │ │ ├── AdminAssetModifyReqDto.java │ │ │ │ ├── AdminAssetResDto.java │ │ │ │ ├── AdminDealResDto.java │ │ │ │ ├── AdminMarketResDto.java │ │ │ │ ├── AdminStockResDto.java │ │ │ │ ├── AdminUserInfoResDto.java │ │ │ │ ├── AdminUserModifyReqDto.java │ │ │ │ └── AdminUserResDto.java │ │ │ └── service │ │ │ │ ├── AdminAssetService.java │ │ │ │ ├── AdminAssetServiceImpl.java │ │ │ │ ├── AdminDealService.java │ │ │ │ ├── AdminDealServiceImpl.java │ │ │ │ ├── AdminMarketService.java │ │ │ │ ├── AdminMarketServiceImpl.java │ │ │ │ ├── AdminUserService.java │ │ │ │ └── AdminUserServiceImpl.java │ │ ├── auction │ │ │ ├── controller │ │ │ │ └── AuctionController.java │ │ │ ├── dto │ │ │ │ ├── AuctionReqDto.java │ │ │ │ └── AuctionResDto.java │ │ │ ├── entity │ │ │ │ └── AuctionEntity.java │ │ │ ├── repository │ │ │ │ └── AuctionRepository.java │ │ │ └── service │ │ │ │ ├── AuctionService.java │ │ │ │ └── AuctionServiceImpl.java │ │ ├── bank │ │ │ ├── controller │ │ │ │ └── BankController.java │ │ │ ├── dto │ │ │ │ ├── BankReqDto.java │ │ │ │ ├── MyBankResDto.java │ │ │ │ ├── MyTotalResDto.java │ │ │ │ └── TransferReqDto.java │ │ │ ├── entity │ │ │ │ └── BankEntity.java │ │ │ ├── repository │ │ │ │ └── BankRepository.java │ │ │ └── service │ │ │ │ ├── BankService.java │ │ │ │ └── BankServiceImpl.java │ │ ├── comment │ │ │ ├── controller │ │ │ │ └── CommentController.java │ │ │ ├── dto │ │ │ │ ├── AuthorResDto.java │ │ │ │ ├── CommentListResDto.java │ │ │ │ └── CommentResDto.java │ │ │ ├── entity │ │ │ │ └── CommentEntity.java │ │ │ ├── repository │ │ │ │ └── CommentRepository.java │ │ │ └── service │ │ │ │ ├── CommentService.java │ │ │ │ └── CommentServiceImpl.java │ │ ├── minigame │ │ │ ├── controller │ │ │ │ └── MiniGameController.java │ │ │ ├── dto │ │ │ │ └── MiniGameResDto.java │ │ │ └── service │ │ │ │ ├── MiniGameService.java │ │ │ │ └── MiniGameServiceImpl.java │ │ ├── mypage │ │ │ ├── controller │ │ │ │ └── MyPageController.java │ │ │ ├── dto │ │ │ │ ├── HomeModifyReqDto.java │ │ │ │ ├── HomeResDto.java │ │ │ │ └── MyAssetResDto.java │ │ │ └── service │ │ │ │ ├── MyPageService.java │ │ │ │ └── MyPageServiceImpl.java │ │ ├── news │ │ │ ├── controller │ │ │ │ └── NewsController.java │ │ │ ├── dto │ │ │ │ ├── DateListResDto.java │ │ │ │ ├── NewsReqDto.java │ │ │ │ ├── NewsResDto.java │ │ │ │ └── StockNewsListResDto.java │ │ │ ├── entity │ │ │ │ ├── NewsEntity.java │ │ │ │ └── UserNewsEntity.java │ │ │ ├── repository │ │ │ │ ├── NewsRepository.java │ │ │ │ └── UserNewsRepository.java │ │ │ └── service │ │ │ │ ├── NewsService.java │ │ │ │ └── NewsServiceImpl.java │ │ ├── rank │ │ │ ├── controller │ │ │ │ └── RankController.java │ │ │ ├── dto │ │ │ │ └── RankResDto.java │ │ │ ├── entity │ │ │ │ └── RankEntity.java │ │ │ ├── repository │ │ │ │ └── RankRepository.java │ │ │ └── service │ │ │ │ ├── RankService.java │ │ │ │ └── RankServiceImpl.java │ │ ├── stock │ │ │ ├── controller │ │ │ │ └── StockController.java │ │ │ ├── dto │ │ │ │ ├── DealResDto.java │ │ │ │ ├── ExchangeResDto.java │ │ │ │ ├── MaterialResDto.java │ │ │ │ ├── StockChartResDto.java │ │ │ │ ├── StockInfoResDto.java │ │ │ │ ├── StockListResDto.java │ │ │ │ ├── StockReqDto.java │ │ │ │ └── StockResDto.java │ │ │ ├── entity │ │ │ │ ├── ChartEntity.java │ │ │ │ ├── CompanyEntity.java │ │ │ │ ├── DealStockEntity.java │ │ │ │ ├── ExchangeEntity.java │ │ │ │ ├── MarketEntity.java │ │ │ │ ├── MaterialEntity.java │ │ │ │ ├── StockEntity.java │ │ │ │ └── UserDealEntity.java │ │ │ ├── repository │ │ │ │ ├── ChartRepository.java │ │ │ │ ├── CompanyRepository.java │ │ │ │ ├── DealStockRepository.java │ │ │ │ ├── ExchangeRepository.java │ │ │ │ ├── MarketRepository.java │ │ │ │ ├── MaterialRepository.java │ │ │ │ ├── StockRepository.java │ │ │ │ └── UserDealRepository.java │ │ │ └── service │ │ │ │ ├── StockService.java │ │ │ │ └── StockServiceImpl.java │ │ ├── storage │ │ │ ├── controller │ │ │ │ └── StorageController.java │ │ │ ├── dto │ │ │ │ └── AuctionHistoryResDto.java │ │ │ └── service │ │ │ │ ├── StorageService.java │ │ │ │ └── StorageServiceImpl.java │ │ ├── store │ │ │ ├── controller │ │ │ │ └── StoreController.java │ │ │ ├── dto │ │ │ │ └── AssetResDto.java │ │ │ ├── entity │ │ │ │ ├── AssetEntity.java │ │ │ │ ├── AssetPriceEntity.java │ │ │ │ ├── UserAssetEntity.java │ │ │ │ └── UserAssetLocation.java │ │ │ ├── repository │ │ │ │ ├── AssetPriceRepository.java │ │ │ │ ├── AssetRepository.java │ │ │ │ ├── UserAssetLocationRepository.java │ │ │ │ └── UserAssetRepository.java │ │ │ └── service │ │ │ │ ├── StoreService.java │ │ │ │ └── StoreServiceImpl.java │ │ └── user │ │ │ ├── controller │ │ │ ├── LoginController.java │ │ │ └── UserController.java │ │ │ ├── dto │ │ │ ├── LoginReqDto.java │ │ │ ├── LoginResDto.java │ │ │ ├── UserInfoLoginResDto.java │ │ │ ├── UserInfoReqDto.java │ │ │ ├── UserInfoResDto.java │ │ │ ├── UserResDto.java │ │ │ ├── UsersModifyReqDto.java │ │ │ └── UsersRegisterReqDto.java │ │ │ ├── entity │ │ │ └── UserEntity.java │ │ │ ├── repository │ │ │ └── UserRepository.java │ │ │ └── service │ │ │ ├── CustomUserDetailsService.java │ │ │ ├── LoginService.java │ │ │ ├── LoginServiceImpl.java │ │ │ ├── UserService.java │ │ │ └── UserServiceImpl.java │ │ ├── exception │ │ ├── CustomException.java │ │ ├── ErrorCode.java │ │ ├── ErrorResponse.java │ │ └── GlobalExceptionHandler.java │ │ └── security │ │ └── SpringSecurity.java │ └── test │ └── java │ └── com │ └── server │ └── back │ └── BackApplicationTests.java ├── data-crawling ├── .gitignore ├── README.md ├── change.ipynb ├── crawling.ipynb ├── data │ ├── exchange │ │ ├── data(cur_20141031).p │ │ ├── data(cur_20180831).p │ │ ├── data(cur_20211028).p │ │ └── data(cur_20221231).p │ ├── ir │ │ ├── LG전자.json │ │ ├── LG화학.json │ │ ├── SK텔레콤.json │ │ ├── ir_data.json │ │ ├── naver.json │ │ ├── 녹십자.json │ │ ├── 롯데케미칼.json │ │ ├── 삼성전자.json │ │ └── 셀트리온.json │ ├── material │ │ ├── data(domestic_gold_230414).p │ │ ├── data(national_gold_230414).p │ │ ├── data(oil_gsl_230414).p │ │ └── data(oil_lo_230414).p │ ├── news │ │ ├── data(news_LG전자_230420).p │ │ ├── data(news_LG화학_230418)_real_final_final.p │ │ ├── data(news_SK텔레콤_230420).p │ │ ├── data(news_naver_230417)_real_final_final.p │ │ ├── data(news_녹십자_230420).p │ │ ├── data(news_롯데케미칼_230420).p │ │ ├── data(news_삼성전자_230418)_real_final_final.p │ │ ├── data(news_셀트리온_230419)_2.p │ │ └── data(news_셀트리온_230419)_real_final_final.p │ ├── nnp │ │ ├── nnp_company.csv │ │ ├── nnp_people.csv │ │ ├── nnp_product.csv │ │ └── nnp_result.csv │ └── stock │ │ ├── data(stock_LG전자_230420).p │ │ ├── data(stock_LG화학_230418).p │ │ ├── data(stock_SK텔레콤_230420).p │ │ ├── data(stock_네이버_230416).p │ │ ├── data(stock_녹십자_230420).p │ │ ├── data(stock_롯데케미칼_230420).p │ │ ├── data(stock_삼성전자_230418).p │ │ └── data(stock_셀트리온_230418).p ├── db │ ├── from-currency to-exchange 변환.sql │ ├── from-material to-market 변환.sql │ ├── from-news_origin to-news 변환.sql │ ├── from-stock to-chart 변환.sql │ ├── modoostock_news_origin.sql │ └── pk_init.sql ├── environments.txt ├── konlpy.ipynb ├── masking.ipynb ├── openai.ipynb └── requirements.txt ├── exec ├── img │ ├── data.png │ └── front-back-server.png ├── modoostock_db_dump │ ├── modoostock-db-dump(20230519).zip │ ├── modoostock_all_dump.sql │ ├── modoostock_asset.sql │ ├── modoostock_asset_price.sql │ ├── modoostock_auction.sql │ ├── modoostock_bank.sql │ ├── modoostock_chart.sql │ ├── modoostock_comment.sql │ ├── modoostock_company.sql │ ├── modoostock_deal.sql │ ├── modoostock_deal_stock.sql │ ├── modoostock_exchange.sql │ ├── modoostock_hibernate_sequence.sql │ ├── modoostock_market.sql │ ├── modoostock_material.sql │ ├── modoostock_news.sql │ ├── modoostock_rank_table.sql │ ├── modoostock_stock.sql │ ├── modoostock_user_asset.sql │ ├── modoostock_user_asset_location.sql │ ├── modoostock_user_deal.sql │ ├── modoostock_user_news.sql │ └── modoostock_user_table.sql ├── porting_manual.md └── 시연시나리오.docx └── front-server ├── .gitignore ├── .prettierrc ├── Dockerfile ├── config-overrides.js ├── deploy-conf └── nginx.conf ├── package.json ├── public ├── .well-known │ └── assetlinks.json ├── favicon.ico ├── firebase-messaging-sw.js ├── index.html ├── manifest.json ├── open.wav └── robots.txt ├── src ├── App.css ├── App.test.tsx ├── App.tsx ├── Components │ ├── Admin │ │ ├── AdminAsset.tsx │ │ ├── AdminAssetModal.tsx │ │ ├── AdminDeal.tsx │ │ ├── AdminDealModal.tsx │ │ ├── AdminMain.tsx │ │ ├── AdminMarket.tsx │ │ ├── AdminMarketModal.tsx │ │ ├── AdminPage.tsx │ │ ├── AdminUser.tsx │ │ └── AdminUserModal.tsx │ ├── Auction │ │ ├── Auction.tsx │ │ └── AuctionModal.tsx │ ├── Bank │ │ ├── Bank.tsx │ │ ├── BankModal.tsx │ │ ├── BankSection1.tsx │ │ ├── BankSection2.tsx │ │ └── BankSection3.tsx │ ├── Chatting │ │ ├── Chat.tsx │ │ ├── Chatting.tsx │ │ ├── ChemiChatting.tsx │ │ ├── ElectricChatting.tsx │ │ ├── ITChatting.tsx │ │ ├── LifeChatting.tsx │ │ ├── Message.tsx │ │ ├── NewsInfo.tsx │ │ └── SystemChatting.tsx │ ├── Common │ │ ├── AssetLoading.tsx │ │ ├── ConfirmModal.tsx │ │ ├── Error.tsx │ │ ├── Loading.tsx │ │ ├── Lottie │ │ │ ├── 133381-house-pop-up.json │ │ │ ├── 140765-money.json │ │ │ ├── 94992-error-404.json │ │ │ ├── 96583-ufo-stealing-money.json │ │ │ ├── bluegift.json │ │ │ ├── blueopen.json │ │ │ ├── mailbox.json │ │ │ ├── money.json │ │ │ ├── money2.json │ │ │ ├── redgift.json │ │ │ ├── redopen.json │ │ │ ├── rotateDevice.json │ │ │ ├── yellowgift.json │ │ │ └── yellowopen.json │ │ ├── Navbar.tsx │ │ ├── PrivacyPolicy.tsx │ │ ├── RotateDevice.tsx │ │ ├── SetPushToken.tsx │ │ └── Toast.tsx │ ├── Exchange │ │ ├── Chart.tsx │ │ ├── CountdownTimeMinute.tsx │ │ ├── CountdownTimer.tsx │ │ ├── Exchange.module.css │ │ ├── Exchange.tsx │ │ ├── IRModal.tsx │ │ ├── MobileInfo.tsx │ │ ├── NewsModal.tsx │ │ ├── StockTradeModal.tsx │ │ └── ir_data.json │ ├── GachaShop │ │ └── GachaShop.tsx │ ├── InfoShop │ │ ├── InfoModal.tsx │ │ ├── InfoNewsDetailModal.tsx │ │ └── InfoShop.tsx │ ├── Intro │ │ └── Intro.tsx │ ├── Login │ │ └── Login.tsx │ ├── Main │ │ ├── Guide.tsx │ │ ├── Main.tsx │ │ ├── Modal.tsx │ │ ├── MyHomeAsset.tsx │ │ ├── MyHomeAsset2.tsx │ │ ├── ShowMyRoomAssets.tsx │ │ ├── SundayModal.tsx │ │ └── VisitModal.tsx │ ├── Menu │ │ ├── Menu.tsx │ │ └── UpdateInfo.tsx │ ├── MiniGame │ │ ├── Lottery.module.css │ │ ├── Lottery.tsx │ │ └── LotteryModal.tsx │ ├── Mypage │ │ ├── AllAssetsList.tsx │ │ ├── Mypage.module.css │ │ ├── Mypage.tsx │ │ └── MypageInven.tsx │ ├── Rank │ │ ├── Rank.module.css │ │ └── Rank.tsx │ ├── SignUp │ │ └── SignUp.tsx │ └── Travel │ │ ├── AllAssetsList2.tsx │ │ ├── DeleteGuestBookModal.tsx │ │ ├── GuestBookList.tsx │ │ ├── Travel.tsx │ │ └── WirteGuestBookModal.tsx ├── Layout.tsx ├── Store │ ├── FirebaseApi.ts │ ├── NonAuthApi.ts │ ├── api.ts │ ├── hooks.ts │ └── store.ts ├── firebase.tsx ├── index.css ├── index.tsx ├── intro │ ├── IntroBG.png │ ├── money.png │ └── newspaper.png ├── logo.svg ├── react-app-env.d.ts ├── reportWebVitals.ts ├── service-worker.ts ├── serviceWorkerRegistration.ts └── setupTests.ts ├── tailwind.config.js ├── tsconfig.json └── yarn.lock /README/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/README/image-1.png -------------------------------------------------------------------------------- /README/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/README/image.png -------------------------------------------------------------------------------- /README/남규.md: -------------------------------------------------------------------------------- 1 | # 캬 2 | 3 | - 계획표 작성 4 | - 프로젝트 아키텍쳐 구성 5 | - 기술 스택 정리 6 | - 230413 : 데이터 수집 시작 7 | - 환율 : 20110101 ~ 20141031 8 | - 석유 : 크롤링 작성 중 9 | - 230414 10 | - 환율 : 20141101 ~ 20180831 11 | - 석유, 금 시세 크롤링 완? 12 | - 230417 13 | - 석유, 금 시세 크롤링 완 14 | - 환율 완 15 | - 주식 -> 코드 완(종목 선택해야함) 16 | - 뉴스 -> 코드 수정 중 17 | - 230418 18 | - 뉴스 수집 크롤링 코드 완(하루마다 최대 5개) 19 | - 뉴스 타이틀 마스킹 코드 테스트 20 | - 230419 21 | - 뉴스 타이틀 마스킹 테스트 22 | - 데이터 가공(주식, 시장지표, 환율, 뉴스) -> 초기 데이터 dump 파일 생성 23 | - 230420 24 | - 8개 데이터 수집 완료(엔터테이먼트는 뉴스 정보가 부실하여 삭제) 25 | - 시퀀스 다이어그램, 환경 구성 등 26 | - 230424 27 | - 기업 공시 정보 구조 구성 28 | - 기업 공시 정보 수동으로 작업하기..ing 29 | - 230425 30 | - 기업 공시 정보 수동으로 작업하기..ing2(3개 완) 31 | - 집가서 더 해야겠다.. 32 | - 230426 33 | - 기업 공시 정보 수동 작업 완! 34 | - 스케줄링할거 준비해두기 35 | - 230428 36 | - 스케줄링 기초 완료 37 | - 관리자 api 목업 완료 38 | - 230501 39 | - 스케줄링 완료 40 | - 관리자 API 완료 41 | - 마스킹 코드 완료(OPEN AI API 활용하는 코드) 42 | - 230504 43 | - 모든 기사 제목에서 명사 추출 44 | - 명사에서 수동으로 기업명, 제품명, 사람 이름만 추출 45 | -------------------------------------------------------------------------------- /README/상현.assets/image-20230413174438384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/README/상현.assets/image-20230413174438384.png -------------------------------------------------------------------------------- /README/송빈.md: -------------------------------------------------------------------------------- 1 | 2023-04-11 2 | 3 | - 와이어프레임 작성 4 | - 아이디어 회의 5 | - 아이디어 구체화 6 | 7 | ![image.png](./image.png) 8 | 9 | ![image-1.png](./image-1.png) 10 | -------------------------------------------------------------------------------- /README/애림.md: -------------------------------------------------------------------------------- 1 | ## 2023.04.11 2 | - 아이디어 구체화 3 | - 아이디어 기획 4 | - 계획서 작성 5 | - 와이어프레임 6 | 7 | 8 | ## 2023.04.13 9 | - 와이어프레임 디자인 (main, mypage) 10 | 11 | 12 | ## 2023.04.14 13 | - 와이어프레임 디자인 (정보상, 주식거래소) 14 | 15 | ## 2023.04.17 16 | - 와이어프레임 수정 ( 상점, 경매장, 전체적인 디자인 ) 17 | 18 | ## 2023.04.18 19 | - 와이어프레임 완성 20 | 21 | ## 2023.04.21 22 | - ppt 23 | -------------------------------------------------------------------------------- /README/현아.md: -------------------------------------------------------------------------------- 1 | 2 | ## 2023.04.11 3 | - 아이디어 구체화 4 | - 아이디어 기획 5 | - 계획서 작성 6 | 7 | 8 | ## 2023.04.13 9 | - [ERD 설계](https://www.erdcloud.com/d/PW3gYYNc6SHaCHFgF) 10 | 11 | 12 | ## 2023.04.14 13 | - ERD 설계 다시 수정 14 | ![ERD 설계 다시 수정](https://user-images.githubusercontent.com/109887404/231990225-26ae8eda-4e39-44a4-bd4d-c7395eeaea9f.PNG) 15 | - API DTO 설계 16 | -------------------------------------------------------------------------------- /README/홍민.md: -------------------------------------------------------------------------------- 1 | 2023-04-11 2 | 3 | - 와이어프레임 작성 4 | - 아이디어 회의 5 | - 아이디어 구체화 6 | 7 | 2023-04-12 8 | 9 | - 와이어프레임 10 | - 에셋 체크 11 | 12 | 2023-04-13 13 | 14 | - Threejs 15 | - position, rotate, size → range input 으로 변경 16 | - assets 개별 적용 17 | 18 | 2023-04-14 19 | 20 | - 와이어프레임 21 | - 은행, 여행 22 | - API, ERD 확인 23 | -------------------------------------------------------------------------------- /back-server/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | .metadata 17 | bin/ 18 | !**/src/main/**/bin/ 19 | !**/src/test/**/bin/ 20 | 21 | ### IntelliJ IDEA ### 22 | .idea 23 | *.iws 24 | *.iml 25 | *.ipr 26 | out/ 27 | !**/src/main/**/out/ 28 | !**/src/test/**/out/ 29 | 30 | ### NetBeans ### 31 | /nbproject/private/ 32 | /nbbuild/ 33 | /dist/ 34 | /nbdist/ 35 | /.nb-gradle/ 36 | 37 | ### VS Code ### 38 | .vscode/ 39 | -------------------------------------------------------------------------------- /back-server/BackendSever.md: -------------------------------------------------------------------------------- 1 | # 💻BackEnd Server 2 | 3 | - 빈 디렉토리는 `dump.txt`로 채워두었스빈다! 4 | 5 | ## 변경해 주세요!! 6 | - 일단 초기 DB는 localhost로 잡아뒀습니다. 필요하시면 수정하시고 사용하시면 됩니다. 7 | - `src/main/resources/application.properties` 파일에서 수정합니다. 8 | ```properties 9 | # mysql 10 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 11 | # serverTimezone=Asia/Seoul : 사용하는 DB의 타임존을 서울로 타임존 설정 12 | # zeroDateTimeBehavior=convertToNull : zero date(0000-00-00 00:00:00)로 저장된 경우 null로 받아오게 설정 13 | spring.datasource.url=jdbc:mysql://[IP 주소]]:3306/[DB명]?serverTimezone=Asia/Seoul&zeroDateTimeBehavior=convertToNull 14 | spring.datasource.username=MySQL아이디 15 | spring.datasource.password=MySQL비밀번호 16 | ``` 17 | 18 | ## 프로젝트 구조 19 | ``` 20 | main 21 | ├─java 22 | │ └─com 23 | │ └─server 24 | │ └─back 25 | │ ├─common 26 | │ │ ├─auth 27 | │ │ │ ├─dto 28 | │ │ │ ├─entity 29 | │ │ │ ├─repository 30 | │ │ │ └─service 31 | │ │ ├─dto 32 | │ │ ├─entity 33 | │ │ ├─repository 34 | │ │ └─service 35 | │ ├─config 36 | │ ├─domain 37 | │ │ └─sample 38 | │ │ ├─controller 39 | │ │ ├─dto 40 | │ │ ├─entity 41 | │ │ ├─repository 42 | │ │ └─service 43 | │ ├─exception 44 | │ │ 45 | │ └─security 46 | └─resources 47 | ├─static 48 | └─templates 49 | ``` 50 | -------------------------------------------------------------------------------- /back-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM adoptopenjdk/openjdk11 AS builder 2 | 3 | COPY gradlew . 4 | COPY gradle gradle 5 | COPY build.gradle . 6 | COPY settings.gradle . 7 | COPY src src 8 | RUN chmod +x ./gradlew 9 | RUN ./gradlew bootJAR 10 | 11 | FROM adoptopenjdk/openjdk11 12 | COPY --from=builder build/libs/*.jar app.jar 13 | EXPOSE 8080 14 | ENTRYPOINT ["java", "-jar", "-Duser.timezone=Asia/Seoul", "/app.jar"] 15 | -------------------------------------------------------------------------------- /back-server/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.server' 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-data-jpa' 23 | implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' 24 | implementation 'org.springframework.boot:spring-boot-starter-security' 25 | implementation 'org.springframework.boot:spring-boot-starter-web' 26 | 27 | implementation 'io.springfox:springfox-boot-starter:3.0.0' 28 | 29 | compileOnly 'org.projectlombok:lombok' 30 | developmentOnly 'org.springframework.boot:spring-boot-devtools' 31 | runtimeOnly 'com.mysql:mysql-connector-j' 32 | annotationProcessor 'org.projectlombok:lombok' 33 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 34 | testImplementation 'org.springframework.security:spring-security-test' 35 | 36 | // Validation 37 | implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.7.5' 38 | 39 | // sms 40 | implementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.13' 41 | 42 | //Redis 43 | implementation 'org.springframework.boot:spring-boot-starter-data-redis' 44 | implementation 'io.lettuce:lettuce-core:6.1.5.RELEASE' 45 | 46 | // jjwt 47 | implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1' 48 | } 49 | 50 | tasks.named('test') { 51 | useJUnitPlatform() 52 | } 53 | -------------------------------------------------------------------------------- /back-server/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/back-server/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /back-server/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 | -------------------------------------------------------------------------------- /back-server/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'back' 2 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/BackApplication.java: -------------------------------------------------------------------------------- 1 | package com.server.back; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cache.annotation.EnableCaching; 6 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | 9 | import javax.annotation.PostConstruct; 10 | import java.util.TimeZone; 11 | 12 | @EnableCaching 13 | @EnableJpaAuditing 14 | @EnableScheduling 15 | @SpringBootApplication 16 | public class BackApplication { 17 | 18 | @PostConstruct 19 | public void started() { 20 | // timezone Asia/Seoul 셋팅 21 | TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); 22 | } 23 | 24 | public static void main(String[] args) { 25 | SpringApplication.run(BackApplication.class, args); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/AssetColorType.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum AssetColorType { 4 | Material, LP_Rooms; 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/AssetLevelType.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | import lombok.Getter; 4 | import lombok.ToString; 5 | 6 | @Getter 7 | @ToString 8 | public enum AssetLevelType implements TypeModel{ 9 | RARE("낮은 단계"), 10 | EPIC("증간 단계"), 11 | UNIQUE("높은 단계"), 12 | LEGENDARY("가장 높은 단계"); 13 | 14 | private final String description; 15 | 16 | AssetLevelType(String description) { 17 | this.description = description; 18 | } 19 | 20 | public static AssetLevelType of(String assetLevelStr){ 21 | for(AssetLevelType assetlevel:AssetLevelType.values()){ 22 | if(assetlevel.getName().equals(assetLevelStr)){ 23 | return assetlevel; 24 | } 25 | } 26 | throw new IllegalArgumentException("일치하는 ASSET LEVEL이 없습니다."); 27 | } 28 | @Override 29 | public String getName() { 30 | return name(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/DealType.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | 4 | import lombok.Getter; 5 | 6 | 7 | @Getter 8 | public enum DealType implements TypeModel{ 9 | GET_MONEY_FOR_STOCK("주식팔아서 돈 얻기"), 10 | GET_MONEY_FOR_AUCTION("경매에서 돈 얻기"), 11 | GET_MONEY_FOR_DEPOSIT("예금깨서 돈 얻기"), 12 | GET_MONEY_FOR_RESALE("은행에 되팔기"), 13 | GET_MONEY_FOR_DAILY("하루에 한 번 돈 받기"), 14 | GET_MONEY_FOR_TRANSFER("송금에서 돈 얻기"), 15 | GET_MONEY_FOR_BLOTTO("스피드에서 돈 얻기"), 16 | GET_MONEY_FOR_DLOTTO("어둠의 복권에서 돈 얻기"), 17 | LOSE_MONEY_FOR_STOCK("주식 사서 돈 까먹기"), 18 | LOSE_MONEY_FOR_AUCTION("경매에서 사서 돈 까먹기"), 19 | LOSE_MONEY_FOR_DEPOSIT("예금에 돈 넣기"), 20 | LOSE_MONEY_FOR_INFO("정보 사기"), 21 | LOSE_MONEY_FOR_ASSET("에셋 사기"), 22 | LOSE_MONEY_FOR_TRANSFER("송금에서 돈 주기"), 23 | LOSE_MONEY_FOR_BLOTTO("스피드 복권 사기"), 24 | LOSE_MONEY_FOR_DLOTTO("어둠의 복권 사기"); 25 | 26 | private final String description; 27 | 28 | DealType(String description) { 29 | this.description = description; 30 | } 31 | 32 | @Override 33 | public String getName() { 34 | return name(); 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/GotchaLevel.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public enum GotchaLevel implements TypeModel{ 7 | LOW("낮은 단계 갓차"), 8 | MIDDLE("증간 단계 갓차"), 9 | HIGH("높은 단계 갓차"); 10 | 11 | private final String description; 12 | 13 | GotchaLevel(String description) { 14 | this.description = description; 15 | } 16 | 17 | public static GotchaLevel of(String gotchaStr){ 18 | for(GotchaLevel gotcha:GotchaLevel.values()){ 19 | if(gotcha.getName().equals(gotchaStr)){ 20 | return gotcha; 21 | } 22 | } 23 | throw new IllegalArgumentException("일치하는 GOTCHA LEVEL이 없습니다."); 24 | } 25 | @Override 26 | public String getName() { 27 | return name(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/IsAuctioned.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum IsAuctioned { 4 | Y,N; 5 | } 6 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/IsAuthor.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum IsAuthor { 4 | Y,N; 5 | } 6 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/IsCompleted.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum IsCompleted { 4 | Y,N 5 | } 6 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/IsDeleted.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum IsDeleted { 4 | Y,N; 5 | } 6 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/IsInRespository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum IsInRespository { 4 | Y,N; 5 | } 6 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/IsUsed.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | public enum IsUsed { 4 | Y,N; 5 | } 6 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/Role.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | import lombok.Getter; 4 | 5 | @Getter 6 | public enum Role implements TypeModel { 7 | USER("ROLE_USER"), 8 | ADMIN("ROLE_USER,ROLE_ADMIN"); 9 | 10 | @Override 11 | public String getName() { 12 | return name(); 13 | } 14 | 15 | private final String description; 16 | 17 | Role(String description) { 18 | this.description = description; 19 | } 20 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/TypeGroup.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | 4 | import lombok.Getter; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | 11 | @Getter 12 | public enum TypeGroup { 13 | Deal(Arrays.stream(DealType.values()).collect(Collectors.toList())); 14 | private final List typeList; 15 | 16 | TypeGroup(List typeList) { 17 | this.typeList = typeList; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/commonCode/TypeModel.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.commonCode; 2 | 3 | 4 | public interface TypeModel { 5 | String getName(); 6 | String getDescription(); 7 | } 8 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/controller/CommonCodeController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.controller; 2 | 3 | import com.server.back.common.code.commonCode.TypeGroup; 4 | import com.server.back.common.code.commonCode.TypeModel; 5 | import com.server.back.common.code.dto.ResultDto; 6 | import io.swagger.annotations.Api; 7 | import io.swagger.annotations.ApiOperation; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | import java.util.stream.Collectors; 16 | 17 | @RestController 18 | @RequiredArgsConstructor 19 | @Api(tags = "공통 코드 API") 20 | public class CommonCodeController { 21 | @GetMapping("/type") 22 | @ApiOperation(value = "공통 코드 전체 목록을 조회합니다.") 23 | public ResponseEntity>>> getCommonCode() { 24 | Map> totalTypeMap = new HashMap<>(); // <공통 그룹 코드, 공통 코드들> 로 묶음 25 | 26 | for (TypeGroup typeGroup : TypeGroup.values()) { 27 | Map typeMap = typeGroup.getTypeList().stream() // group에 속한 공통 코드들을 list에서 map<코드, 설명>으로 변환 28 | .collect(Collectors.toMap( 29 | TypeModel::getName, 30 | TypeModel::getDescription)); 31 | 32 | totalTypeMap.put(typeGroup.name(), typeMap); 33 | } 34 | return ResponseEntity.ok(ResultDto.of(totalTypeMap)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/dto/ResultDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.dto; 2 | 3 | 4 | import lombok.*; 5 | 6 | 7 | @Getter 8 | @Setter 9 | @ToString 10 | //@RequiredArgsConstructor 11 | @AllArgsConstructor 12 | @NoArgsConstructor 13 | public class ResultDto { 14 | 15 | private T data; 16 | private ResultEnum result; 17 | 18 | 19 | public static ResultDto of(T data, ResultEnum result) { 20 | return new ResultDto<>(data, result); 21 | } 22 | 23 | 24 | public static ResultDto of(T data) { 25 | return new ResultDto<>(data, ResultEnum.SUCCESS); 26 | } 27 | 28 | 29 | public static ResultDto ofSuccess() { 30 | return new ResultDto<>(Boolean.TRUE, ResultEnum.SUCCESS); 31 | } 32 | 33 | 34 | public static ResultDto ofFail() { 35 | return new ResultDto<>(Boolean.FALSE, ResultEnum.FAIL); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/code/dto/ResultEnum.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.code.dto; 2 | 3 | public enum ResultEnum { 4 | SUCCESS("SUCCESS"), 5 | FAIL("FAIL"); 6 | 7 | private final String msg; 8 | 9 | 10 | ResultEnum(String msg) { 11 | this.msg = msg; 12 | } 13 | 14 | 15 | @Override 16 | public String toString() { 17 | return this.msg; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/entity/CommonEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.entity; 2 | 3 | 4 | import lombok.AccessLevel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | import lombok.experimental.SuperBuilder; 9 | import org.springframework.data.annotation.CreatedDate; 10 | import org.springframework.data.annotation.LastModifiedDate; 11 | import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters.LocalDateTimeConverter; 12 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 13 | 14 | import javax.persistence.Column; 15 | import javax.persistence.Convert; 16 | import javax.persistence.EntityListeners; 17 | import javax.persistence.MappedSuperclass; 18 | import java.time.LocalDateTime; 19 | 20 | @MappedSuperclass 21 | @AllArgsConstructor(access = AccessLevel.PROTECTED) 22 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 23 | @Getter 24 | @SuperBuilder 25 | @EntityListeners(AuditingEntityListener.class) 26 | public abstract class CommonEntity { 27 | 28 | @CreatedDate 29 | @Column(updatable = false, nullable = false) 30 | @Convert(converter = LocalDateTimeConverter.class) 31 | private LocalDateTime createdAt; 32 | 33 | @LastModifiedDate 34 | @Column(nullable = false) 35 | @Convert(converter = LocalDateTimeConverter.class) 36 | private LocalDateTime updatedAt; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/entity/DealEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.entity; 2 | 3 | 4 | import com.server.back.common.code.commonCode.DealType; 5 | import com.server.back.domain.user.entity.UserEntity; 6 | import lombok.*; 7 | import lombok.experimental.SuperBuilder; 8 | 9 | import javax.persistence.*; 10 | 11 | @Entity 12 | @Getter 13 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 14 | @AllArgsConstructor 15 | @SuperBuilder 16 | @Inheritance(strategy = InheritanceType.JOINED) 17 | @DiscriminatorColumn(name = "deal_code") 18 | @Table(name = "deal") 19 | public class DealEntity extends CommonEntity { 20 | 21 | @Id 22 | @GeneratedValue(strategy = GenerationType.IDENTITY) 23 | private Long id; 24 | 25 | @ManyToOne(fetch = FetchType.LAZY) 26 | @JoinColumn(name = "user_id", nullable = false) 27 | private UserEntity user; 28 | 29 | @Column(nullable = false) 30 | private Long price; 31 | 32 | @Column(nullable = false) 33 | @Enumerated(EnumType.STRING) 34 | private DealType dealType; 35 | 36 | public DealEntity(UserEntity user, DealType dealType, Long price){ 37 | this.user=user; 38 | this.dealType=dealType; 39 | this.price=price; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/repository/DealRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.repository; 2 | 3 | import com.server.back.common.code.commonCode.DealType; 4 | import com.server.back.common.entity.DealEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | public interface DealRepository extends JpaRepository { 12 | Optional findByUserIdAndDealTypeAndCreatedAtGreaterThanEqual(Long userId, DealType dealType, LocalDateTime startDatetime); 13 | 14 | List findByUserId(Long userId); 15 | } 16 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/service/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.service; 2 | 3 | 4 | import com.server.back.domain.user.entity.UserEntity; 5 | import com.server.back.exception.CustomException; 6 | import com.server.back.exception.ErrorCode; 7 | import lombok.RequiredArgsConstructor; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.security.core.context.SecurityContextHolder; 10 | import org.springframework.stereotype.Service; 11 | 12 | 13 | @Service 14 | @Slf4j 15 | @RequiredArgsConstructor 16 | public class AuthService { 17 | 18 | 19 | public Long getUserId() { 20 | Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 21 | if (principal != null && principal instanceof UserEntity) { 22 | UserEntity user = (UserEntity) principal; 23 | return user.getId(); 24 | } else { 25 | log.error("Context에 유저 정보가 저장되어있지 않습니다."); 26 | throw new CustomException(ErrorCode.UNAUTHORIZED_USER); 27 | } 28 | } 29 | 30 | 31 | public String getUserNickname() { 32 | Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 33 | if (principal != null && principal instanceof UserEntity) { 34 | UserEntity user = (UserEntity) principal; 35 | return user.getNickname(); 36 | } else { 37 | log.error("Context에 유저 정보가 저장되어있지 않습니다."); 38 | throw new CustomException(ErrorCode.UNAUTHORIZED_USER); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/common/service/RedisService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.common.service; 2 | 3 | 4 | import lombok.RequiredArgsConstructor; 5 | import org.springframework.data.redis.core.StringRedisTemplate; 6 | import org.springframework.data.redis.core.ValueOperations; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.time.Duration; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | 13 | @RequiredArgsConstructor 14 | @Service 15 | public class RedisService { 16 | 17 | private final StringRedisTemplate stringRedisTemplate; 18 | 19 | 20 | // key를 통해 value 리턴 21 | public String getData(String key) { 22 | ValueOperations valueOperations = stringRedisTemplate.opsForValue(); 23 | return valueOperations.get(key); 24 | } 25 | 26 | 27 | // 유효 시간 동안(key, value)저장 28 | public void setDataExpire(String key, String value, long duration) { 29 | ValueOperations valueOperations = stringRedisTemplate.opsForValue(); 30 | Duration expireDuration = Duration.ofSeconds(duration); 31 | valueOperations.set(key, value, expireDuration); 32 | } 33 | 34 | 35 | // 유효 시간 동안(key, value)저장 36 | public void setDataExpireMilliseconds(String key, String value, long duration) { 37 | ValueOperations valueOperations = stringRedisTemplate.opsForValue(); 38 | valueOperations.set(key, value, duration, TimeUnit.MILLISECONDS); 39 | } 40 | 41 | 42 | public void deleteData(String key) { 43 | stringRedisTemplate.delete(key); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.server.back.config; 2 | 3 | 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | 9 | @Configuration 10 | public class CorsConfig implements WebMvcConfigurer { 11 | 12 | @Override 13 | public void addCorsMappings(CorsRegistry registry) { 14 | //todo 15 | registry.addMapping("/**") 16 | .allowedOrigins("http://localhost:8080", "http://localhost:3000", "https://k8e206.p.ssafy.io", "https://modoostock.com") 17 | .allowedMethods("GET", "POST", "PUT", "DELETE") 18 | .exposedHeaders("Access-Control-Allow-Headers, Authorization, X-Refresh-Token") 19 | .allowCredentials(true); 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/config/JwtExceptionFilter.java: -------------------------------------------------------------------------------- 1 | package com.server.back.config; 2 | 3 | 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import com.server.back.common.code.dto.ResultEnum; 6 | import io.jsonwebtoken.JwtException; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.http.MediaType; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.web.filter.OncePerRequestFilter; 11 | 12 | import javax.servlet.FilterChain; 13 | import javax.servlet.ServletException; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.io.IOException; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | 21 | @Slf4j 22 | @Component 23 | public class JwtExceptionFilter extends OncePerRequestFilter { 24 | 25 | @Override 26 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 27 | try { 28 | filterChain.doFilter(request, response); // JwtAuthenticationFilter로 이동 29 | } catch (JwtException ex) { 30 | // JwtAuthenticationFilter에서 예외 발생하면 바로 setErrorResponse 호출 31 | setErrorResponse(request, response, ex); 32 | } 33 | } 34 | 35 | 36 | public void setErrorResponse(HttpServletRequest req, HttpServletResponse res, Throwable ex) throws IOException { 37 | 38 | res.setContentType(MediaType.APPLICATION_JSON_VALUE); 39 | 40 | final Map body = new HashMap<>(); 41 | body.put("status", HttpServletResponse.SC_UNAUTHORIZED); 42 | body.put("error", "Unauthorized"); 43 | // ex.getMessage() 에는 jwtException을 발생시키면서 입력한 메세지가 들어있다. 44 | body.put("message", ex.getMessage()); 45 | body.put("path", req.getServletPath()); 46 | body.put("result", ResultEnum.FAIL); 47 | final ObjectMapper mapper = new ObjectMapper(); 48 | mapper.writeValue(res.getOutputStream(), body); 49 | res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/config/JwtSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.server.back.config; 2 | 3 | 4 | import com.server.back.common.service.AuthTokenProvider; 5 | import com.server.back.common.service.RedisService; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.security.config.annotation.SecurityConfigurerAdapter; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.web.DefaultSecurityFilterChain; 11 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 12 | 13 | 14 | // 직접 만든 TokenProvider 와 JwtFilter 를 SecurityConfig 에 적용할 때 사용 15 | @Slf4j 16 | @RequiredArgsConstructor 17 | public class JwtSecurityConfig extends SecurityConfigurerAdapter { 18 | 19 | private final AuthTokenProvider tokenProvider; 20 | private final RedisService redisService; 21 | private final JwtExceptionFilter jwtExceptionFilter; 22 | 23 | 24 | // TokenProvider 를 주입받아서 JwtFilter 를 통해 Security 로직에 필터를 등록 25 | @Override 26 | public void configure(HttpSecurity http) { 27 | JwtFilter customFilter = new JwtFilter(tokenProvider, redisService); 28 | http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); 29 | http.addFilterBefore(jwtExceptionFilter, customFilter.getClass()); 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/controller/AdminAssetController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.controller; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.common.code.dto.ResultDto; 5 | import com.server.back.domain.admin.dto.AdminAssetModifyReqDto; 6 | import com.server.back.domain.admin.dto.AdminAssetResDto; 7 | import com.server.back.domain.admin.service.AdminAssetService; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiOperation; 10 | import lombok.RequiredArgsConstructor; 11 | import org.springframework.http.ResponseEntity; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import java.util.List; 15 | 16 | @RestController 17 | @RequestMapping("/admin/asset") 18 | @RequiredArgsConstructor 19 | @Api(tags="관리자 에셋 API") 20 | public class AdminAssetController { 21 | private final AdminAssetService adminAssetService; 22 | @GetMapping 23 | @ApiOperation(value = "검색한 에셋 정보를 반환합니다.", notes = "") 24 | public ResponseEntity>> getAssetList(@RequestParam(required = false, name = "assetLevel")AssetLevelType assetLevel, @RequestParam(required = false, name = "category")String category){ 25 | List assetList= adminAssetService.getAssetList(assetLevel, category); 26 | return ResponseEntity.ok(ResultDto.of(assetList)); 27 | } 28 | @PutMapping 29 | @ApiOperation(value = "에셋 정보를 수정합니다", notes = "") 30 | public ResponseEntity> updateAsset(@RequestBody AdminAssetModifyReqDto reqDto){ 31 | adminAssetService.updateAsset(reqDto); 32 | return ResponseEntity.ok(ResultDto.ofSuccess()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/controller/AdminDealController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.admin.dto.AdminDealResDto; 5 | import com.server.back.domain.admin.dto.AdminUserResDto; 6 | import com.server.back.domain.admin.service.AdminDealService; 7 | import io.swagger.annotations.Api; 8 | import io.swagger.annotations.ApiOperation; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PathVariable; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import java.util.List; 17 | 18 | @RestController 19 | @RequestMapping("/admin/deal") 20 | @RequiredArgsConstructor 21 | @Api(tags="관리자 거래내역 API") 22 | public class AdminDealController { 23 | private final AdminDealService adminDealService; 24 | @GetMapping 25 | @ApiOperation(value = "모든 거래 내역을 조회합니다", notes = "") 26 | public ResponseEntity>> getDealList(){ 27 | List dealList= adminDealService.getDealList(); 28 | return ResponseEntity.ok(ResultDto.of(dealList)); 29 | } 30 | @GetMapping("/{account}") 31 | @ApiOperation(value = "검색한 회원의 모든 거래 내역을 조회합니다", notes = "") 32 | public ResponseEntity>> getUserDealList(@PathVariable(name = "account")String account){ 33 | List dealList= adminDealService.getDealList(account); 34 | return ResponseEntity.ok(ResultDto.of(dealList)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/controller/AdminMarketController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.admin.dto.AdminDealResDto; 5 | import com.server.back.domain.admin.dto.AdminMarketResDto; 6 | import com.server.back.domain.admin.dto.AdminStockResDto; 7 | import com.server.back.domain.admin.service.AdminMarketService; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiOperation; 10 | import lombok.RequiredArgsConstructor; 11 | import org.springframework.http.ResponseEntity; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.PathVariable; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RestController; 16 | 17 | import java.util.List; 18 | 19 | @RestController 20 | @RequestMapping("/admin/market") 21 | @RequiredArgsConstructor 22 | @Api(tags="관리자 장(시즌) API") 23 | public class AdminMarketController { 24 | private final AdminMarketService adminMarketService; 25 | @GetMapping 26 | @ApiOperation(value = "모든 장(시즌) 목록을 조회합니다.", notes = "") 27 | public ResponseEntity>> getMarketList(){ 28 | List marketList= adminMarketService.getMarketList(); 29 | return ResponseEntity.ok(ResultDto.of(marketList)); 30 | } 31 | @GetMapping("/{marketId}") 32 | @ApiOperation(value = "선택한 장(시즌)의 종목 목록을 조회합니다.", notes = "") 33 | public ResponseEntity>> getMarketInfo(@PathVariable(name = "marketId")Long marketId){ 34 | List marketInfoList= adminMarketService.getMarketStockList(marketId); 35 | return ResponseEntity.ok(ResultDto.of(marketInfoList)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminAssetModifyReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.store.entity.AssetEntity; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | /** 11 | * 관리자 에셋 정보 수정 12 | */ 13 | @Builder 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class AdminAssetModifyReqDto { 18 | private Long assetId; 19 | private String category; 20 | private AssetLevelType assetLevel; 21 | 22 | public AssetEntity toEntity(AssetEntity asset) { 23 | return AssetEntity.builder() 24 | .id(asset.getId()) 25 | .assetLevel(this.assetLevel) 26 | .category((this.category)) 27 | .build(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminAssetResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.store.entity.AssetEntity; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | @Data 12 | @Builder 13 | public class AdminAssetResDto { 14 | private Long assetId; 15 | private String assetImagePath; 16 | private AssetLevelType assetLevel; 17 | private String assetCategory; 18 | 19 | public static AdminAssetResDto fromEntity(AssetEntity asset){ 20 | return AdminAssetResDto.builder() 21 | .assetId(asset.getId()) 22 | .assetLevel(asset.getAssetLevel()) 23 | .assetCategory(asset.getCategory()) 24 | .build(); 25 | } 26 | 27 | public static List fromEntityList(List assetEntityList){ 28 | return assetEntityList.stream().map(AdminAssetResDto::fromEntity).collect(Collectors.toList()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminMarketResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import com.server.back.domain.stock.entity.MarketEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDate; 8 | import java.time.LocalDateTime; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Data 13 | @Builder 14 | public class AdminMarketResDto { 15 | private Long marketId; 16 | private LocalDateTime createAt; 17 | private LocalDate startAt; 18 | private LocalDate endAt; 19 | private LocalDate gameDate; 20 | 21 | public static AdminMarketResDto fromEntity(MarketEntity marketEntity){ 22 | return AdminMarketResDto.builder() 23 | .marketId(marketEntity.getId()) 24 | .createAt(marketEntity.getCreatedAt()) 25 | .startAt(marketEntity.getStartAt()) 26 | .endAt(marketEntity.getEndAt()) 27 | .gameDate(marketEntity.getGameDate()) 28 | .build(); 29 | } 30 | 31 | public static List fromEntityList(List marketEntityList){ 32 | return marketEntityList.stream().map(AdminMarketResDto::fromEntity).collect(Collectors.toList()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminStockResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import com.server.back.domain.stock.entity.StockEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | @Data 11 | @Builder 12 | public class AdminStockResDto { 13 | private String companyName; 14 | private String companyKind; 15 | private Long average; 16 | public static AdminStockResDto fromEntity(StockEntity stockEntity){ 17 | return AdminStockResDto.builder() 18 | .companyName(stockEntity.getCompany().getName()) 19 | .companyKind(stockEntity.getCompany().getKind()) 20 | .average(stockEntity.getAverage()) 21 | .build(); 22 | } 23 | public static List fromEntityList(List stockEntityList){ 24 | return stockEntityList.stream().map(AdminStockResDto::fromEntity).collect(Collectors.toList()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminUserInfoResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder 9 | public class AdminUserInfoResDto { 10 | private Long userId; 11 | private String account; 12 | private String nickname; 13 | private String introduction; 14 | private String profileImagePath; 15 | private Long currentMoney; 16 | 17 | public static AdminUserInfoResDto fromEntity(UserEntity user){ 18 | return AdminUserInfoResDto.builder() 19 | .userId(user.getId()) 20 | .account(user.getAccount()) 21 | .nickname(user.getNickname()) 22 | .introduction(user.getIntroduction()) 23 | .profileImagePath(user.getProfileImagePath()) 24 | .currentMoney(user.getCurrentMoney()) 25 | .build(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminUserModifyReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * 관리자 회원 정보 수정 10 | */ 11 | @Builder 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class AdminUserModifyReqDto { 16 | private Long userId; 17 | private String nickname; 18 | } 19 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/dto/AdminUserResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | @Data 11 | @Builder 12 | public class AdminUserResDto { 13 | private Long userId; 14 | private String account; 15 | private String nickname; 16 | private String introduction; 17 | 18 | public static AdminUserResDto fromEntity(UserEntity user) { 19 | return AdminUserResDto.builder() 20 | .userId(user.getId()) 21 | .account(user.getAccount()) 22 | .nickname(user.getNickname()) 23 | .introduction(user.getIntroduction()) 24 | .build(); 25 | } 26 | 27 | public static List fromEntityList(List userList){ 28 | return userList.stream().map(AdminUserResDto::fromEntity).collect(Collectors.toList()); 29 | } 30 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminAssetService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.admin.dto.AdminAssetModifyReqDto; 5 | import com.server.back.domain.admin.dto.AdminAssetResDto; 6 | 7 | import java.util.List; 8 | 9 | public interface AdminAssetService { 10 | List getAssetList(AssetLevelType assetLevel, String category); 11 | 12 | void updateAsset(AdminAssetModifyReqDto reqDto); 13 | } 14 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminAssetServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.admin.dto.AdminAssetModifyReqDto; 5 | import com.server.back.domain.admin.dto.AdminAssetResDto; 6 | import com.server.back.domain.store.entity.AssetEntity; 7 | import com.server.back.domain.store.repository.AssetRepository; 8 | import com.server.back.exception.CustomException; 9 | import com.server.back.exception.ErrorCode; 10 | import lombok.RequiredArgsConstructor; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.stereotype.Service; 13 | 14 | import java.util.List; 15 | 16 | @Slf4j 17 | @Service 18 | @RequiredArgsConstructor 19 | public class AdminAssetServiceImpl implements AdminAssetService{ 20 | private final AssetRepository assetRepository; 21 | /** 22 | * 검색한 에셋 정보를 반환합니다. 23 | * 24 | * @return 검색된 에셋들 25 | */ 26 | @Override 27 | public List getAssetList(AssetLevelType assetLevel, String category) { 28 | List assetEntityList; 29 | if((assetLevel != null) && (category != null)){ 30 | assetEntityList = assetRepository.findByAssetLevelAndCategory(assetLevel, category); 31 | }else if(assetLevel != null){ 32 | assetEntityList = assetRepository.findByAssetLevel(assetLevel); 33 | } 34 | else if(category != null){ 35 | assetEntityList = assetRepository.findByCategory(category); 36 | } 37 | else assetEntityList = assetRepository.findAll(); 38 | return AdminAssetResDto.fromEntityList(assetEntityList); 39 | } 40 | /** 41 | * 에셋 정보를 수정합니다. 42 | * 43 | */ 44 | @Override 45 | public void updateAsset(AdminAssetModifyReqDto reqDto) { 46 | AssetEntity asset = assetRepository.findById(reqDto.getAssetId()).orElseThrow(() -> new CustomException(ErrorCode.ENTITY_NOT_FOUND)); 47 | AssetEntity assetEntity = reqDto.toEntity(asset); 48 | assetRepository.save(assetEntity); 49 | } 50 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminDealService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.domain.admin.dto.AdminDealResDto; 4 | 5 | import java.util.List; 6 | 7 | public interface AdminDealService { 8 | List getDealList(); 9 | 10 | List getDealList(String account); 11 | } 12 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminDealServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.common.entity.DealEntity; 4 | import com.server.back.common.repository.DealRepository; 5 | import com.server.back.domain.admin.dto.AdminDealResDto; 6 | import com.server.back.domain.stock.entity.DealStockEntity; 7 | import com.server.back.domain.user.entity.UserEntity; 8 | import com.server.back.domain.user.repository.UserRepository; 9 | import com.server.back.exception.CustomException; 10 | import com.server.back.exception.ErrorCode; 11 | import lombok.RequiredArgsConstructor; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.List; 16 | 17 | @Slf4j 18 | @Service 19 | @RequiredArgsConstructor 20 | public class AdminDealServiceImpl implements AdminDealService{ 21 | private final UserRepository userRepository; 22 | private final DealRepository dealRepository; 23 | /** 24 | * 모든 거래 내역을 반환합니다. 25 | * 26 | * @return 검색된 거래 내역들 27 | */ 28 | @Override 29 | public List getDealList() { 30 | List dealEntityList = dealRepository.findAll(); 31 | return AdminDealResDto.fromEntityList(dealEntityList); 32 | } 33 | /** 34 | * 검색한 사용자의 거래 내역을 반환합니다. 35 | * 36 | * @return 검색된 거래 내역들 37 | */ 38 | @Override 39 | public List getDealList(String account) { 40 | UserEntity userEntity = userRepository.findByAccount(account).orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); 41 | List dealEntityList = dealRepository.findByUserId(userEntity.getId()); 42 | return AdminDealResDto.fromEntityList(dealEntityList); 43 | } 44 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminMarketService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.domain.admin.dto.AdminMarketResDto; 4 | import com.server.back.domain.admin.dto.AdminStockResDto; 5 | 6 | import java.util.List; 7 | 8 | public interface AdminMarketService { 9 | List getMarketList(); 10 | 11 | List getMarketStockList(Long marketId); 12 | } 13 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminMarketServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.domain.admin.dto.AdminMarketResDto; 4 | import com.server.back.domain.admin.dto.AdminStockResDto; 5 | import com.server.back.domain.stock.entity.MarketEntity; 6 | import com.server.back.domain.stock.entity.StockEntity; 7 | import com.server.back.domain.stock.repository.MarketRepository; 8 | import com.server.back.domain.stock.repository.StockRepository; 9 | import com.server.back.exception.CustomException; 10 | import com.server.back.exception.ErrorCode; 11 | import lombok.RequiredArgsConstructor; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.Collections; 16 | import java.util.List; 17 | 18 | @Slf4j 19 | @Service 20 | @RequiredArgsConstructor 21 | public class AdminMarketServiceImpl implements AdminMarketService{ 22 | private final MarketRepository marketRepository; 23 | private final StockRepository stockRepository; 24 | /** 25 | * 모든 장(시즌) 검색합니다. 26 | * 27 | * @return 검색된 장들 28 | */ 29 | @Override 30 | public List getMarketList() { 31 | List marketEntityList = marketRepository.findAll(); 32 | Collections.reverse(marketEntityList); 33 | return AdminMarketResDto.fromEntityList(marketEntityList); 34 | } 35 | 36 | /** 37 | * 선택한 장의 모든 종목을 검색합니다. 38 | * 39 | * @return 검색된 종목들 40 | */ 41 | @Override 42 | public List getMarketStockList(Long marketId) { 43 | List stockEntityList = stockRepository.findByMarket_Id(marketId); 44 | if(stockEntityList.isEmpty()) throw new CustomException(ErrorCode.ENTITY_NOT_FOUND); 45 | return AdminStockResDto.fromEntityList(stockEntityList); 46 | } 47 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/admin/service/AdminUserService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.admin.service; 2 | 3 | import com.server.back.domain.admin.dto.AdminUserInfoResDto; 4 | import com.server.back.domain.admin.dto.AdminUserModifyReqDto; 5 | import com.server.back.domain.admin.dto.AdminUserResDto; 6 | 7 | import java.util.List; 8 | 9 | public interface AdminUserService { 10 | List getUserList(); 11 | 12 | List getUserList(String type, String keyword); 13 | 14 | AdminUserInfoResDto getUserInfo(String account); 15 | 16 | void updateUser(AdminUserModifyReqDto reqDto); 17 | 18 | void deleteUser(String account); 19 | 20 | boolean getUserIsAdmin(); 21 | } 22 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/auction/dto/AuctionReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.auction.dto; 2 | 3 | import com.server.back.common.code.commonCode.IsCompleted; 4 | import com.server.back.common.code.commonCode.IsDeleted; 5 | import com.server.back.domain.auction.entity.AuctionEntity; 6 | import com.server.back.domain.store.entity.UserAssetEntity; 7 | import lombok.*; 8 | 9 | @Getter 10 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 11 | @AllArgsConstructor 12 | public class AuctionReqDto { 13 | private Long userAssetId; 14 | private Long price; 15 | 16 | public AuctionEntity toEntity(UserAssetEntity userAsset){ 17 | return AuctionEntity.builder() 18 | .userAsset(userAsset) 19 | .auctionPrice(price) 20 | .isCompleted(IsCompleted.N) 21 | .isDeleted(IsDeleted.N) 22 | .build(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/auction/dto/AuctionResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.auction.dto; 2 | 3 | import com.server.back.domain.auction.entity.AuctionEntity; 4 | import com.server.back.domain.store.dto.AssetResDto; 5 | import com.server.back.domain.user.dto.UserInfoResDto; 6 | import com.server.back.domain.user.entity.UserEntity; 7 | import lombok.*; 8 | 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Data 13 | @Builder 14 | public class AuctionResDto { 15 | private Long auctionId; 16 | private AssetResDto assetResDto; 17 | private String account; 18 | private String nickname; 19 | private Long price; 20 | 21 | public static AuctionResDto fromEntity(AuctionEntity auction){ 22 | AssetResDto assetResDto=AssetResDto.fromEntity(auction.getUserAsset().getAsset()); 23 | UserEntity userEntity = auction.getUserAsset().getUser(); 24 | return AuctionResDto.builder() 25 | .auctionId(auction.getId()) 26 | .assetResDto(assetResDto) 27 | .account(userEntity.getAccount()) 28 | .nickname(userEntity.getNickname()) 29 | .price(auction.getAuctionPrice()) 30 | .build(); 31 | } 32 | public static List fromEntityList(List auctionList ){ 33 | return auctionList.stream().map(AuctionResDto::fromEntity).collect(Collectors.toList()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/auction/entity/AuctionEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.auction.entity; 2 | 3 | import com.server.back.common.code.commonCode.IsCompleted; 4 | import com.server.back.common.code.commonCode.IsDeleted; 5 | import com.server.back.common.entity.CommonEntity; 6 | import com.server.back.domain.store.entity.UserAssetEntity; 7 | import lombok.*; 8 | 9 | import javax.persistence.*; 10 | 11 | @Entity 12 | @Getter 13 | @Builder 14 | @Table(name="auction") 15 | @AllArgsConstructor 16 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 17 | public class AuctionEntity extends CommonEntity { 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private Long id; 21 | 22 | @OneToOne 23 | @JoinColumn(name = "user_asset_id",nullable = false) 24 | private UserAssetEntity userAsset; 25 | 26 | @Column(nullable = false) 27 | private Long auctionPrice; 28 | 29 | @Column(nullable = false) 30 | private IsCompleted isCompleted; 31 | 32 | @Column(nullable = false) 33 | private IsDeleted isDeleted; 34 | 35 | public void update(IsDeleted isDeleted){ 36 | this.isDeleted=isDeleted; 37 | } 38 | public void update(IsCompleted isCompleted){ 39 | this.isCompleted=isCompleted; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/auction/repository/AuctionRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.auction.repository; 2 | 3 | import com.server.back.common.code.commonCode.IsCompleted; 4 | import com.server.back.common.code.commonCode.IsDeleted; 5 | import com.server.back.domain.auction.entity.AuctionEntity; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | public interface AuctionRepository extends JpaRepository { 12 | List findAllByIsDeletedAndIsCompletedOrderByCreatedAtDesc(IsDeleted isDeleted,IsCompleted isCompleted); 13 | Optional findByIdAndIsDeletedAndIsCompleted(Long auctionId, IsDeleted isDeleted, IsCompleted isCompleted); 14 | List findAllByUserAssetUserIdAndIsCompletedAndIsDeletedOrderByCreatedAtDesc(Long userId,IsCompleted isCompleted,IsDeleted isDeleted); 15 | List findAllByUserAssetAssetIdAndIsCompletedAndIsDeletedOrderByCreatedAtDesc(Long assetId,IsCompleted isCompleted,IsDeleted isDeleted); 16 | Optional findByUserAssetIdAndIsCompletedAndIsDeleted(Long myAssetId, IsCompleted isCompleted, IsDeleted isDeleted); 17 | } 18 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/auction/service/AuctionService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.auction.service; 2 | 3 | import com.server.back.domain.auction.dto.AuctionReqDto; 4 | import com.server.back.domain.auction.dto.AuctionResDto; 5 | 6 | import java.util.List; 7 | 8 | public interface AuctionService { 9 | 10 | List getAuctionList(); 11 | 12 | AuctionResDto getAuctionDetail(Long auctionId); 13 | 14 | void participateAuction(Long auctionId); 15 | 16 | void deleteAuction(Long auctionId); 17 | 18 | void createAuction(AuctionReqDto auctionReqDto); 19 | 20 | List getMyAuctionList(); 21 | 22 | void deleteMyPageAuction(Long myAssetId); 23 | } 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/dto/BankReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.dto; 2 | 3 | import com.server.back.common.code.commonCode.DealType; 4 | import com.server.back.domain.bank.entity.BankEntity; 5 | import com.server.back.domain.user.entity.UserEntity; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class BankReqDto { 14 | private Long price; 15 | 16 | public BankEntity toEntity(UserEntity user) { 17 | return BankEntity.builder() 18 | .user(user) 19 | .price(price) 20 | .dealType(DealType.LOSE_MONEY_FOR_DEPOSIT) 21 | .interest(Math.round(price * 0.02)) 22 | .build(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/dto/MyBankResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.dto; 2 | 3 | import com.server.back.domain.bank.entity.BankEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | import static com.server.back.domain.bank.service.BankServiceImpl.BANK_PERIOD; 12 | 13 | @Data 14 | @Builder 15 | public class MyBankResDto { 16 | 17 | Long bankId; 18 | LocalDateTime startDate; 19 | LocalDateTime endDate; 20 | Long price; 21 | Boolean isPaid; 22 | 23 | public static MyBankResDto fromEntity(BankEntity bank) { 24 | // 기본으로 은행에 넣었던 돈 얻기 25 | Long getMoney = bank.getPrice(); 26 | // 만기일 27 | LocalDateTime endDate = bank.getCreatedAt().plusHours(BANK_PERIOD); 28 | 29 | // 이자 지급 여부 30 | Boolean isPaid = false; 31 | 32 | // 만기가 지났다면 이자 추가 33 | if (LocalDateTime.now().isAfter(endDate)){ 34 | getMoney += bank.getInterest(); 35 | isPaid = true; 36 | } 37 | 38 | return MyBankResDto.builder().bankId(bank.getId()).startDate(bank.getCreatedAt()).endDate(endDate).price(getMoney).isPaid(isPaid).build(); 39 | } 40 | 41 | public static List fromEnityList(List bankList ){ 42 | return bankList.stream().map(MyBankResDto::fromEntity).collect(Collectors.toList()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/dto/MyTotalResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.dto; 2 | 3 | import lombok.Builder; 4 | import lombok.Data; 5 | 6 | 7 | @Data 8 | @Builder 9 | public class MyTotalResDto { 10 | Long currentMoney; 11 | 12 | public static MyTotalResDto fromEntity(Long currentMoney) { 13 | return MyTotalResDto.builder().currentMoney(currentMoney).build(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/dto/TransferReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | @Data 8 | @NoArgsConstructor 9 | @AllArgsConstructor 10 | public class TransferReqDto { 11 | private String receiver; 12 | private Long money; 13 | } 14 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/entity/BankEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.entity; 2 | 3 | import com.server.back.common.code.commonCode.IsCompleted; 4 | import com.server.back.common.entity.DealEntity; 5 | import lombok.*; 6 | import lombok.experimental.SuperBuilder; 7 | 8 | import javax.persistence.*; 9 | 10 | @Entity 11 | @Getter 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | @SuperBuilder 15 | @DiscriminatorValue("DEAL_BANK") 16 | @Table(name = "bank") 17 | public class BankEntity extends DealEntity { 18 | 19 | @Column(nullable = false) 20 | private Long interest; 21 | 22 | @Column(nullable = false) 23 | @Enumerated(EnumType.STRING) 24 | @Builder.Default 25 | private IsCompleted isCompleted = IsCompleted.N; 26 | 27 | 28 | public void setIsCompleted(IsCompleted isCompleted) { 29 | this.isCompleted = isCompleted; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/repository/BankRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.repository; 2 | 3 | import com.server.back.common.code.commonCode.IsCompleted; 4 | import com.server.back.domain.bank.entity.BankEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Query; 7 | import org.springframework.data.repository.query.Param; 8 | 9 | import java.util.List; 10 | import java.util.Optional; 11 | 12 | public interface BankRepository extends JpaRepository { 13 | Optional findByIdAndAndIsCompleted(Long id, IsCompleted isCompleted); 14 | List findByUserIdAndIsCompleted(Long userId, IsCompleted isCompleted); 15 | 16 | @Query("SELECT SUM(d.price) FROM BankEntity d WHERE d.user.id = :userId AND d.isCompleted = :isCompleted") 17 | Optional getPriceSumByUserIdAndIsCompleted(@Param("userId") Long userId, @Param("isCompleted") IsCompleted isCompleted); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/bank/service/BankService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.bank.service; 2 | 3 | import com.server.back.domain.bank.dto.BankReqDto; 4 | import com.server.back.domain.bank.dto.MyBankResDto; 5 | import com.server.back.domain.bank.dto.MyTotalResDto; 6 | import com.server.back.domain.bank.dto.TransferReqDto; 7 | 8 | import java.util.List; 9 | 10 | public interface BankService { 11 | void createBankAccount(BankReqDto bankReqDto); 12 | void deleteBankAccount(Long bankId); 13 | List getBankAccountList(); 14 | MyTotalResDto getBankTotal(); 15 | void transfer(TransferReqDto transferReqDto); 16 | } 17 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/controller/CommentController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.comment.dto.CommentListResDto; 5 | import com.server.back.domain.comment.service.CommentService; 6 | import io.swagger.annotations.Api; 7 | import io.swagger.annotations.ApiOperation; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import java.util.List; 13 | 14 | @RestController 15 | @RequestMapping("/comment") 16 | @RequiredArgsConstructor 17 | @Api(tags="방명록 관련 API") 18 | public class CommentController { 19 | 20 | private final CommentService commentService; 21 | 22 | @GetMapping 23 | @ApiOperation(value = "방명록 리스트 반환") 24 | public ResponseEntity>> getCommentList(@RequestParam String nickname){ 25 | List commentList=commentService.getCommentList(nickname); 26 | return ResponseEntity.ok(ResultDto.of(commentList)); 27 | } 28 | 29 | @PostMapping 30 | @ApiOperation(value = "방명록 작성") 31 | public ResponseEntity> createComment(@RequestParam String nickname,@RequestBody String content){ 32 | commentService.createComment(nickname,content); 33 | return ResponseEntity.ok().body(ResultDto.ofSuccess()); 34 | } 35 | 36 | @PutMapping("/{commentId}") 37 | @ApiOperation(value = "방명록 수정") 38 | public ResponseEntity> updateComment(@PathVariable Long commentId,@RequestBody String content){ 39 | commentService.updateComment(commentId,content); 40 | return ResponseEntity.ok().body(ResultDto.ofSuccess()); 41 | 42 | } 43 | 44 | @DeleteMapping("/{commentId}") 45 | @ApiOperation(value = "방명록 삭제") 46 | public ResponseEntity> deleteComment(@PathVariable Long commentId){ 47 | commentService.deleteComment(commentId); 48 | return ResponseEntity.ok().body(ResultDto.ofSuccess()); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/dto/AuthorResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.*; 5 | 6 | @Data 7 | @Builder 8 | public class AuthorResDto { 9 | private String nickname; 10 | private String profileImagePath; 11 | 12 | public static AuthorResDto fromEntity(UserEntity user){ 13 | return AuthorResDto.builder() 14 | .nickname(user.getNickname()) 15 | .profileImagePath(user.getProfileImagePath()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/dto/CommentListResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.dto; 2 | 3 | import com.server.back.common.code.commonCode.IsAuthor; 4 | import lombok.*; 5 | 6 | @Data 7 | @Builder 8 | public class CommentListResDto { 9 | private AuthorResDto authorResDto; 10 | private CommentResDto commentResDto; 11 | private IsAuthor isAuthor; 12 | 13 | public static CommentListResDto toDto(AuthorResDto authorResDto, CommentResDto commentResDto,IsAuthor isAuthor){ 14 | return CommentListResDto.builder() 15 | .isAuthor(isAuthor) 16 | .authorResDto(authorResDto) 17 | .commentResDto(commentResDto) 18 | .build(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/dto/CommentResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.dto; 2 | 3 | import com.server.back.domain.comment.entity.CommentEntity; 4 | import lombok.*; 5 | 6 | @Data 7 | @Builder 8 | public class CommentResDto { 9 | private Long commentId; 10 | private String content; 11 | 12 | public static CommentResDto fromEntity(CommentEntity comment){ 13 | 14 | return CommentResDto.builder() 15 | .commentId(comment.getId()) 16 | .content(comment.getContent()) 17 | .build(); 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/entity/CommentEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.entity; 2 | 3 | import com.server.back.common.code.commonCode.IsDeleted; 4 | import com.server.back.common.entity.CommonEntity; 5 | import lombok.*; 6 | 7 | import javax.persistence.*; 8 | 9 | @Entity 10 | @Builder 11 | @Getter 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | @Table(name = "comment") 15 | public class CommentEntity extends CommonEntity { 16 | @Id 17 | @GeneratedValue 18 | private Long id; 19 | 20 | @Column(nullable = false) 21 | private String content; 22 | 23 | @Column(nullable = false) 24 | private Long authorId; 25 | 26 | @Column(nullable=false) 27 | private Long ownerId; 28 | 29 | @Column(nullable = false) 30 | private IsDeleted isDeleted; 31 | 32 | public void update(String content){ 33 | this.content=content; 34 | } 35 | 36 | public void update(IsDeleted isDeleted){ 37 | this.isDeleted=isDeleted; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/repository/CommentRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.repository; 2 | 3 | import com.server.back.common.code.commonCode.IsDeleted; 4 | import com.server.back.domain.comment.entity.CommentEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | public interface CommentRepository extends JpaRepository { 11 | OptionalfindByIdAndAndIsDeleted(Long id,IsDeleted isDeleted); 12 | List findAllByOwnerIdAndIsDeletedOrderByCreatedAtDesc(Long ownerId, IsDeleted isDeleted); 13 | } 14 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/comment/service/CommentService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.comment.service; 2 | 3 | import com.server.back.domain.comment.dto.CommentListResDto; 4 | 5 | import java.util.List; 6 | 7 | public interface CommentService { 8 | List getCommentList(String nickname); 9 | 10 | void createComment(String nickname,String content); 11 | 12 | void updateComment(Long commentId, String content); 13 | 14 | void deleteComment(Long commentId); 15 | } 16 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/minigame/controller/MiniGameController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.minigame.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.minigame.dto.MiniGameResDto; 5 | import com.server.back.domain.minigame.service.MiniGameService; 6 | import io.swagger.annotations.Api; 7 | import io.swagger.annotations.ApiOperation; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | @RestController 15 | @RequestMapping("/mini") 16 | @RequiredArgsConstructor 17 | @Api(tags = "미니게임 API") 18 | public class MiniGameController { 19 | 20 | private final MiniGameService miniGameService; 21 | 22 | @PostMapping("/bright") 23 | @ApiOperation(value = "스피드 로또에 참여합니다.") 24 | public ResponseEntity> createBrightLotto(){ 25 | MiniGameResDto miniGameResDto=miniGameService.createBrightLotto(); 26 | return ResponseEntity.ok(ResultDto.of(miniGameResDto)); 27 | } 28 | 29 | @PostMapping("/dark") 30 | @ApiOperation(value = "어둠의 복권에 참여합니다.") 31 | public ResponseEntity> createDarkLotto(){ 32 | MiniGameResDto miniGameResDto=miniGameService.createDarkLotto(); 33 | return ResponseEntity.ok(ResultDto.of(miniGameResDto)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/minigame/dto/MiniGameResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.minigame.dto; 2 | 3 | import lombok.*; 4 | 5 | @Data 6 | @Builder 7 | @AllArgsConstructor 8 | public class MiniGameResDto { 9 | private Integer ranking; 10 | private Long money; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/minigame/service/MiniGameService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.minigame.service; 2 | 3 | import com.server.back.domain.minigame.dto.MiniGameResDto; 4 | 5 | public interface MiniGameService { 6 | MiniGameResDto createBrightLotto(); 7 | 8 | MiniGameResDto createDarkLotto(); 9 | } 10 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/mypage/dto/HomeModifyReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.mypage.dto; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Getter 9 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 10 | @AllArgsConstructor 11 | public class HomeModifyReqDto { 12 | 13 | private Long userAssetId; 14 | private float pos_x; 15 | private float pos_y; 16 | private float pos_z; 17 | private float rot_x; 18 | private float rot_y; 19 | private float rot_z; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/mypage/dto/HomeResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.mypage.dto; 2 | 3 | import com.server.back.common.code.commonCode.AssetColorType; 4 | import com.server.back.common.code.commonCode.AssetLevelType; 5 | import com.server.back.domain.store.entity.UserAssetLocation; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Data 13 | @Builder 14 | public class HomeResDto { 15 | private Long userAssetId; 16 | private String assetName; 17 | private String assetNameKor; 18 | private AssetLevelType assetLevel; 19 | private float pos_x; 20 | private float pos_y; 21 | private float pos_z; 22 | private float rot_x; 23 | private float rot_y; 24 | private float rot_z; 25 | 26 | private AssetColorType type; 27 | 28 | public static HomeResDto fromEntity(UserAssetLocation userAssetLocation){ 29 | 30 | AssetColorType type = userAssetLocation.getAsset().getId() > 370 && 422 > userAssetLocation.getAsset().getId() ? AssetColorType.Material : AssetColorType.LP_Rooms; 31 | 32 | return HomeResDto.builder() 33 | .assetName(userAssetLocation.getAsset().getAssetName()) 34 | .assetNameKor(userAssetLocation.getAsset().getAssetNameKor()) 35 | .assetLevel(userAssetLocation.getAsset().getAssetLevel()) 36 | .userAssetId(userAssetLocation.getId()) 37 | .pos_x(userAssetLocation.getPosX()) 38 | .pos_y(userAssetLocation.getPosY()) 39 | .pos_z(userAssetLocation.getPosZ()) 40 | .rot_x(userAssetLocation.getRotX()) 41 | .rot_y(userAssetLocation.getRotY()) 42 | .rot_z(userAssetLocation.getRotZ()) 43 | .type(type) 44 | .build(); 45 | } 46 | 47 | public static List fromEntityList(List userAssetLocationList){ 48 | return userAssetLocationList.stream().map(HomeResDto::fromEntity).collect(Collectors.toList()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/mypage/dto/MyAssetResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.mypage.dto; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.common.code.commonCode.IsAuctioned; 5 | import com.server.back.domain.store.entity.UserAssetEntity; 6 | import lombok.*; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | @Data 12 | @Builder 13 | public class MyAssetResDto { 14 | private Long userAssetId; 15 | private String assetName; 16 | private String assetNameKor; 17 | private AssetLevelType assetLevel; 18 | private String assetCategory; 19 | private IsAuctioned isAuctioned; 20 | 21 | public static MyAssetResDto fromEntity(UserAssetEntity userAsset){ 22 | return MyAssetResDto.builder() 23 | .userAssetId(userAsset.getId()) 24 | .assetName(userAsset.getAsset().getAssetName()) 25 | .assetNameKor(userAsset.getAsset().getAssetNameKor()) 26 | .assetLevel(userAsset.getAsset().getAssetLevel()) 27 | .assetCategory(userAsset.getAsset().getCategory()) 28 | .isAuctioned(userAsset.getIsAuctioned()) 29 | .build(); 30 | } 31 | 32 | public static List fromEntityList(List userAssetEntityList ){ 33 | return userAssetEntityList.stream().map(MyAssetResDto::fromEntity).collect(Collectors.toList()); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/mypage/service/MyPageService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.mypage.service; 2 | 3 | import com.server.back.domain.mypage.dto.HomeModifyReqDto; 4 | import com.server.back.domain.mypage.dto.HomeResDto; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.util.List; 9 | 10 | public interface MyPageService { 11 | void updateUserAssetInMyPage(HomeModifyReqDto request); 12 | 13 | void createUserAssetInMyPage(Long myAssetId); 14 | 15 | void deleteUserAssetInMyPage(Long myAssetId); 16 | 17 | List geMyPageMyRoom(String nickname); 18 | 19 | Long getVisitorCount(String nickname,HttpServletRequest request, HttpServletResponse response); 20 | } 21 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/controller/NewsController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.news.dto.NewsReqDto; 5 | import com.server.back.domain.news.dto.NewsResDto; 6 | import com.server.back.domain.news.dto.StockNewsListResDto; 7 | import com.server.back.domain.news.service.NewsService; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiOperation; 10 | import io.swagger.models.Response; 11 | import lombok.RequiredArgsConstructor; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import java.util.List; 16 | 17 | @RestController 18 | @RequestMapping("/info") 19 | @RequiredArgsConstructor 20 | @Api(tags = "뉴스 API") 21 | public class NewsController { 22 | private final NewsService newsService; 23 | 24 | @GetMapping() 25 | @ApiOperation(value="현재 주식 종목 리스트 조회") 26 | public ResponseEntity> getStockList() { 27 | StockNewsListResDto stockNewsListResDto = newsService.getStockList(); 28 | return ResponseEntity.ok().body(ResultDto.of(stockNewsListResDto)); 29 | } 30 | 31 | @PostMapping("/buy") 32 | @ApiOperation(value="선택한 종목의 뉴스 구입") 33 | public ResponseEntity> buyNews(@RequestBody NewsReqDto newsReqDto){ 34 | NewsResDto newsResDto = newsService.buyNews(newsReqDto); 35 | return ResponseEntity.ok().body(ResultDto.of(newsResDto)); 36 | } 37 | @GetMapping("/mine") 38 | @ApiOperation(value="구매한 뉴스 조회") 39 | public ResponseEntity>> getMyNews(){ 40 | List myNews = newsService.getNewsList(); 41 | return ResponseEntity.ok().body(ResultDto.of(myNews)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/dto/DateListResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.dto; 2 | 3 | import com.server.back.domain.stock.entity.ChartEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDate; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | @Data 12 | @Builder 13 | public class DateListResDto { 14 | LocalDate date; 15 | 16 | public static DateListResDto fromEntity(ChartEntity chart){ 17 | return DateListResDto.builder() 18 | .date(chart.getDate()) 19 | .build(); 20 | } 21 | public static List fromEntityList(List chartList) { 22 | return chartList.stream().map(DateListResDto::fromEntity).collect(Collectors.toList()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/dto/NewsReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.dto; 2 | 3 | import com.server.back.domain.news.entity.NewsEntity; 4 | import com.server.back.domain.news.entity.UserNewsEntity; 5 | import com.server.back.domain.user.entity.UserEntity; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import java.time.LocalDate; 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class NewsReqDto { 16 | Long stockId; 17 | 18 | public UserNewsEntity toEntity(UserEntity user, NewsEntity news){ 19 | return UserNewsEntity.builder() 20 | .user(user) 21 | .news(news) 22 | .build(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/dto/NewsResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.dto; 2 | 3 | import com.server.back.domain.news.entity.NewsEntity; 4 | import com.server.back.domain.news.entity.UserNewsEntity; 5 | import com.server.back.domain.stock.dto.StockListResDto; 6 | import com.server.back.domain.stock.entity.StockEntity; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | 10 | import java.time.LocalDate; 11 | import java.util.List; 12 | import java.util.stream.Collectors; 13 | 14 | @Data 15 | @Builder 16 | public class NewsResDto { 17 | private String kind; 18 | private String content; 19 | private LocalDate date; 20 | 21 | public static NewsResDto fromEntity(NewsEntity news) { 22 | return NewsResDto.builder() 23 | .kind(news.getCompany().getKind()) 24 | .content(news.getContent()) 25 | .date(news.getDate()) 26 | .build(); 27 | } 28 | 29 | public static List fromEntityList(List userNews){ 30 | return userNews.stream().map(n -> NewsResDto.fromEntity(n.getNews())).collect(Collectors.toList()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/dto/StockNewsListResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.dto; 2 | 3 | import com.server.back.domain.stock.dto.StockListResDto; 4 | import com.server.back.domain.stock.entity.ChartEntity; 5 | import com.server.back.domain.stock.entity.StockEntity; 6 | import lombok.*; 7 | 8 | import java.util.List; 9 | 10 | @Data 11 | @Builder 12 | public class StockNewsListResDto { 13 | 14 | private List stockList; 15 | 16 | private List dateList; 17 | 18 | public static StockNewsListResDto fromEntity(List stockList, List stockChartList){ 19 | return StockNewsListResDto.builder() 20 | .stockList(StockListResDto.fromEntityList(stockList)) 21 | .dateList(DateListResDto.fromEntityList(stockChartList)) 22 | .build(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/entity/NewsEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.entity; 2 | 3 | import com.server.back.domain.stock.entity.CompanyEntity; 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | import java.time.LocalDate; 9 | import java.time.LocalDateTime; 10 | 11 | @Entity 12 | @Getter 13 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 14 | @AllArgsConstructor 15 | @SuperBuilder 16 | @Table(name="news") 17 | public class NewsEntity { 18 | 19 | @Id 20 | @GeneratedValue(strategy = GenerationType.IDENTITY) 21 | private Long id; 22 | 23 | @ManyToOne(fetch = FetchType.LAZY) 24 | @JoinColumn(name = "company_id", nullable = false) 25 | private CompanyEntity company; 26 | 27 | @Column(nullable = false) 28 | private String content; 29 | 30 | @Column(nullable = false) 31 | private LocalDate date; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/entity/UserNewsEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.entity; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | 9 | @Entity 10 | @Getter 11 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 12 | @AllArgsConstructor 13 | @SuperBuilder 14 | @Table(name = "user_news") 15 | public class UserNewsEntity { 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.IDENTITY) 18 | private Long id; 19 | 20 | @ManyToOne(fetch = FetchType.LAZY) 21 | @JoinColumn(name = "user_id", nullable = false) 22 | private UserEntity user; 23 | 24 | @ManyToOne(fetch = FetchType.LAZY) 25 | @JoinColumn(name = "news_id", nullable = false) 26 | private NewsEntity news; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/repository/NewsRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.repository; 2 | 3 | import com.server.back.domain.news.dto.NewsResDto; 4 | import com.server.back.domain.news.entity.NewsEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.time.LocalDate; 8 | import java.util.List; 9 | 10 | public interface NewsRepository extends JpaRepository{ 11 | List findAllByCompanyIdAndDateBetween(Long companyId,LocalDate startDate, LocalDate endDate); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/repository/UserNewsRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.repository; 2 | 3 | import com.server.back.domain.news.entity.UserNewsEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public interface UserNewsRepository extends JpaRepository { 10 | 11 | Optional findByNewsId(Long id); 12 | List findAllByUserIdOrderByNews_DateDesc(Long userId); 13 | void deleteAllByUserId(Long userId); 14 | } 15 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/news/service/NewsService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.news.service; 2 | 3 | import com.server.back.domain.news.dto.NewsReqDto; 4 | import com.server.back.domain.news.dto.NewsResDto; 5 | import com.server.back.domain.news.dto.StockNewsListResDto; 6 | 7 | import java.util.List; 8 | 9 | public interface NewsService { 10 | NewsResDto buyNews(NewsReqDto newsReqDto); 11 | 12 | StockNewsListResDto getStockList(); 13 | 14 | List getNewsList(); 15 | } 16 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/rank/controller/RankController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.rank.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.rank.dto.RankResDto; 5 | import com.server.back.domain.rank.service.RankService; 6 | import io.swagger.annotations.Api; 7 | import io.swagger.annotations.ApiOperation; 8 | import lombok.RequiredArgsConstructor; 9 | import org.springframework.http.ResponseEntity; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import java.util.List; 15 | 16 | @RestController 17 | @RequestMapping("/rank") 18 | @RequiredArgsConstructor 19 | @Api(tags = "랭킹 API") 20 | public class RankController { 21 | 22 | private final RankService rankService; 23 | 24 | @GetMapping 25 | @ApiOperation(value = "랭킹 리스트를 뽑아줍니다.", notes = "") 26 | public ResponseEntity>> getRanking(){ 27 | Listranking=rankService.getRanking(); 28 | return ResponseEntity.ok(ResultDto.of(ranking)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/rank/dto/RankResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.rank.dto; 2 | 3 | import com.server.back.domain.rank.entity.RankEntity; 4 | import lombok.*; 5 | 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | @Data 10 | @Builder 11 | public class RankResDto { 12 | private String nickname; 13 | private String profileImagePath; 14 | private Long totalMoney; 15 | 16 | public static RankResDto fromEntity(RankEntity rank){ 17 | return RankResDto.builder() 18 | .nickname(rank.getNickname()) 19 | .profileImagePath(rank.getProfileImagePath()) 20 | .totalMoney(rank.getTotalMoney()) 21 | .build(); 22 | } 23 | public static List fromEntityList(Listlist){ 24 | return list.stream().map(RankResDto::fromEntity).collect(Collectors.toList()); 25 | 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/rank/entity/RankEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.rank.entity; 2 | 3 | import lombok.*; 4 | 5 | import javax.persistence.*; 6 | 7 | @Entity 8 | @Getter 9 | @Builder 10 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 11 | @AllArgsConstructor 12 | @Table(name="rank_table") 13 | public class RankEntity { 14 | @Id 15 | @GeneratedValue(strategy = GenerationType.IDENTITY) 16 | private Long id; 17 | 18 | @Column(nullable = false) 19 | private String nickname; 20 | 21 | @Column(nullable = false) 22 | private Long totalMoney; 23 | 24 | @Column(nullable = false) 25 | private String profileImagePath; 26 | 27 | public void update(Long money){ 28 | this.totalMoney+=money; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/rank/repository/RankRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.rank.repository; 2 | 3 | import com.server.back.domain.rank.entity.RankEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public interface RankRepository extends JpaRepository { 10 | List findTop10ByOrderByTotalMoneyDesc(); 11 | Optional findByNickname(String nickname); 12 | } 13 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/rank/service/RankService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.rank.service; 2 | 3 | import com.server.back.domain.rank.dto.RankResDto; 4 | 5 | import java.util.List; 6 | 7 | public interface RankService { 8 | List getRanking(); 9 | } 10 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/DealResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.UserDealEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder 9 | public class DealResDto { 10 | String dealType; 11 | Long price; 12 | Integer amount; 13 | String kind; 14 | 15 | 16 | public static DealResDto fromEntity(String dealType, Long price, Integer amount, String kind){ 17 | return DealResDto.builder() 18 | .dealType(dealType) 19 | .price(price) 20 | .amount(amount) 21 | .kind(kind) 22 | .build(); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/ExchangeResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.ExchangeEntity; 4 | import com.server.back.domain.stock.entity.MaterialEntity; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.time.LocalDate; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Data 13 | @Builder 14 | public class ExchangeResDto { 15 | String nationalCode; 16 | LocalDate date; 17 | 18 | Long price; 19 | 20 | public static ExchangeResDto fromEntity(ExchangeEntity exchange) { 21 | return ExchangeResDto.builder() 22 | .nationalCode(exchange.getNationalCode()) 23 | .date(exchange.getDate()) 24 | .price(exchange.getPrice()) 25 | .build(); 26 | } 27 | 28 | public static List fromEntityList(List exchange) { 29 | return exchange.stream().map(ExchangeResDto::fromEntity).collect(Collectors.toList()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/MaterialResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.MaterialEntity; 4 | import com.server.back.domain.stock.entity.StockEntity; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | 8 | import java.time.LocalDate; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | @Data 13 | @Builder 14 | public class MaterialResDto { 15 | String standardType; 16 | LocalDate date; 17 | Long price; 18 | 19 | public static MaterialResDto fromEntity(MaterialEntity material) { 20 | return MaterialResDto.builder() 21 | .standardType(material.getStandardType()) 22 | .date(material.getDate()) 23 | .price(material.getPrice()) 24 | .build(); 25 | } 26 | 27 | public static List fromEntityList(List material) { 28 | return material.stream().map(MaterialResDto::fromEntity).collect(Collectors.toList()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/StockChartResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.ChartEntity; 4 | import lombok.*; 5 | 6 | import java.time.LocalDate; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Data 11 | @Builder 12 | public class StockChartResDto { 13 | Long priceBefore; 14 | Long priceEnd; 15 | LocalDate date; 16 | Long id; 17 | Long companyId; 18 | Float changeRate; 19 | 20 | public static StockChartResDto fromEntity(ChartEntity chart) { 21 | return StockChartResDto.builder().companyId(chart.getCompany().getId()) 22 | .priceEnd(chart.getPriceEnd()) 23 | .priceBefore(chart.getPriceBefore()) 24 | .date(chart.getDate()) 25 | .id(chart.getId()) 26 | .changeRate(chart.getChangeRate()) 27 | .build(); 28 | } 29 | public static List fromEntityList(List chartList) { 30 | List result = new ArrayList<>(); 31 | ChartEntity prev = null; 32 | for (ChartEntity curr : chartList) { 33 | if (prev == null) { 34 | result.add(StockChartResDto.fromEntity(curr)); 35 | } else { 36 | Long calculatedPriceEnd = prev.getChangeRate() > 0 ? (long) (curr.getPriceEnd() * prev.getChangeRate()) : curr.getPriceEnd(); 37 | StockChartResDto currDto = StockChartResDto.builder() 38 | .companyId(curr.getCompany().getId()) 39 | .priceEnd(calculatedPriceEnd) 40 | .priceBefore(curr.getPriceBefore()) 41 | .date(curr.getDate()) 42 | .id(curr.getId()) 43 | .changeRate(curr.getChangeRate()) 44 | .build(); 45 | result.add(currDto); 46 | } 47 | prev = curr; 48 | } 49 | return result; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/StockInfoResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.ExchangeEntity; 4 | import com.server.back.domain.stock.entity.MaterialEntity; 5 | import com.server.back.domain.stock.entity.StockEntity; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | 9 | import java.util.List; 10 | 11 | @Data 12 | @Builder 13 | public class StockInfoResDto { 14 | private List stockList; 15 | 16 | private List oil; 17 | 18 | private List gold; 19 | 20 | private List usd; 21 | 22 | private List jyp; 23 | 24 | private List euro; 25 | 26 | public static StockInfoResDto fromEntity( 27 | List stockList, List oil, List gold, 28 | List usd, List jyp, List euro){ 29 | return StockInfoResDto.builder() 30 | .stockList(StockListResDto.fromEntityList(stockList)) 31 | .oil(MaterialResDto.fromEntityList(oil)) 32 | .gold(MaterialResDto.fromEntityList(gold)) 33 | .usd(ExchangeResDto.fromEntityList(usd)) 34 | .jyp(ExchangeResDto.fromEntityList(jyp)) 35 | .euro(ExchangeResDto.fromEntityList(euro)) 36 | .build(); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/StockListResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.StockEntity; 4 | import lombok.*; 5 | 6 | import java.util.stream.Collectors; 7 | import java.util.List; 8 | 9 | @Data 10 | @Builder 11 | public class StockListResDto { 12 | Long stockId; 13 | String kind; 14 | Long price; 15 | 16 | public static StockListResDto fromEntity(StockEntity stock) { 17 | return StockListResDto.builder().stockId(stock.getId()).kind(stock.getCompany().getKind()).price(50000L).build(); 18 | } 19 | 20 | public static List fromEntityList(List stockList) { 21 | return stockList.stream().map(StockListResDto::fromEntity).collect(Collectors.toList()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/StockReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.common.code.commonCode.DealType; 4 | import com.server.back.domain.stock.entity.DealStockEntity; 5 | import com.server.back.domain.stock.entity.StockEntity; 6 | import com.server.back.domain.user.entity.UserEntity; 7 | import lombok.AllArgsConstructor; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class StockReqDto { 15 | Long stockId; 16 | Integer stockAmount; 17 | 18 | public DealStockEntity toEntity(UserEntity user, DealType dealType, StockEntity stock, Long chartPrice){ 19 | return DealStockEntity.builder() 20 | .user(user) 21 | .price(chartPrice) 22 | .dealType(dealType) 23 | .stockAmount(stockAmount) 24 | .stock(stock) 25 | .build(); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/dto/StockResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.dto; 2 | 3 | import com.server.back.domain.stock.entity.ChartEntity; 4 | import com.server.back.domain.stock.entity.UserDealEntity; 5 | import lombok.*; 6 | import java.util.*; 7 | 8 | @Data 9 | @Builder 10 | public class StockResDto { 11 | private Long stockId; 12 | private Integer amount; 13 | private Float average; 14 | private Float rate; 15 | private List stockChartResDto; 16 | 17 | public static StockResDto fromEntity(Long stockId, Optional userDeal, List stockChartList) { 18 | if (!userDeal.isPresent()) { 19 | return StockResDto.builder() 20 | .stockId(stockId) 21 | .amount(0) 22 | .average((float) 0) 23 | .rate((float) 0) 24 | .stockChartResDto(StockChartResDto.fromEntityList(stockChartList)) 25 | .build(); 26 | } 27 | return StockResDto.builder().stockId(userDeal.get().getStock().getId()) 28 | .amount(userDeal.get().getTotalAmount()) 29 | .average(userDeal.get().getAverage()) 30 | .rate(userDeal.get().getRate()) 31 | .stockChartResDto(StockChartResDto.fromEntityList(stockChartList)).build(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/ChartEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | import java.time.LocalDate; 9 | 10 | @Entity 11 | @Getter 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | @SuperBuilder 15 | @Table(name = "chart") 16 | public class ChartEntity { 17 | 18 | @Id 19 | @GeneratedValue(strategy = GenerationType.IDENTITY) 20 | private Long id; 21 | 22 | @Column 23 | private Long priceBefore; 24 | 25 | @Column(nullable = false) 26 | private Long priceEnd; 27 | 28 | @Column(nullable = false) 29 | private LocalDate date; 30 | 31 | @ManyToOne(fetch = FetchType.LAZY) 32 | @JoinColumn(name = "company_id", nullable = false) 33 | private CompanyEntity company; 34 | 35 | @Column(nullable = false) 36 | private Long buy; 37 | 38 | @Column(nullable = false) 39 | private Long sell; 40 | 41 | @Column(nullable = false) 42 | private Float changeRate; 43 | 44 | public void buy(Integer amount){ 45 | this.buy += amount; 46 | this.changeRate = (float) (1+((buy-sell)/100)*0.00001); 47 | this.changeRate = changeRate > 1.03F ? 1.03F : changeRate; 48 | this.changeRate = changeRate < 0.97F ? 0.97F : changeRate; 49 | } 50 | 51 | public void sell(Integer amount){ 52 | this.sell += amount; 53 | this.changeRate = (float) (1+((buy-sell)/100)*0.00001); 54 | this.changeRate = changeRate > 1.03F ? 1.03F : changeRate; 55 | this.changeRate = changeRate < 0.97F ? 0.97F : changeRate; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/CompanyEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | import com.server.back.common.code.commonCode.IsUsed; 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | 9 | @Entity 10 | @Getter 11 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 12 | @AllArgsConstructor 13 | @SuperBuilder 14 | @Table(name="company") 15 | public class CompanyEntity { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | 21 | @Column(nullable = false) 22 | private String name; 23 | 24 | @Column(nullable = false) 25 | private String kind; 26 | 27 | @Column(nullable = false) 28 | @Enumerated(EnumType.STRING) 29 | @Builder.Default 30 | private IsUsed isUsed = IsUsed.N; 31 | } 32 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/DealStockEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | import com.server.back.common.entity.DealEntity; 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | 9 | @Entity 10 | @Getter 11 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 12 | @AllArgsConstructor 13 | @SuperBuilder 14 | @Table(name = "deal_stock") 15 | public class DealStockEntity extends DealEntity { 16 | @Column(nullable=false) 17 | private Integer stockAmount; 18 | 19 | @ManyToOne(fetch = FetchType.LAZY) 20 | @JoinColumn(name = "stock_id", nullable = false) 21 | private StockEntity stock; 22 | } 23 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/ExchangeEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | import java.time.LocalDate; 9 | 10 | @Entity 11 | @Getter 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | @SuperBuilder 15 | @Table(name="exchange") 16 | public class ExchangeEntity { 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | 21 | @Column(nullable = false, length = 20) 22 | private String nationalCode; 23 | 24 | @Column(nullable = false) 25 | private LocalDate date; 26 | 27 | @Column(nullable = false) 28 | private Long price; 29 | } 30 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/MarketEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | import com.server.back.common.entity.CommonEntity; 4 | import lombok.*; 5 | import lombok.experimental.SuperBuilder; 6 | 7 | import javax.persistence.*; 8 | import java.time.LocalDate; 9 | 10 | @Entity 11 | @Getter 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | @SuperBuilder 15 | @Table(name = "market") 16 | public class MarketEntity extends CommonEntity { 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | 21 | @Column(nullable = false) 22 | private LocalDate startAt; 23 | 24 | @Column(nullable = false) 25 | private LocalDate endAt; 26 | 27 | @Column(nullable = false) 28 | private LocalDate gameDate; 29 | 30 | public void updateGameDate(LocalDate nextDate) { 31 | this.gameDate = nextDate; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/MaterialEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | import lombok.*; 4 | import lombok.experimental.SuperBuilder; 5 | 6 | import javax.persistence.*; 7 | import java.time.LocalDate; 8 | 9 | @Entity 10 | @Getter 11 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 12 | @AllArgsConstructor 13 | @SuperBuilder 14 | @Table(name="material") 15 | public class MaterialEntity { 16 | 17 | @Id 18 | @GeneratedValue(strategy = GenerationType.IDENTITY) 19 | private Long id; 20 | 21 | @Column(nullable = false, length = 20) 22 | private String standardType; 23 | 24 | @Column(nullable = false) 25 | private LocalDate date; 26 | 27 | @Column(nullable = false) 28 | private Long price; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/entity/StockEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.entity; 2 | 3 | import lombok.*; 4 | import lombok.experimental.SuperBuilder; 5 | 6 | import javax.persistence.*; 7 | 8 | @Entity 9 | @Getter 10 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 11 | @AllArgsConstructor 12 | @SuperBuilder 13 | @Table(name="stock") 14 | public class StockEntity { 15 | 16 | @Id 17 | @GeneratedValue(strategy = GenerationType.IDENTITY) 18 | private Long id; 19 | 20 | @ManyToOne(fetch = FetchType.LAZY) 21 | @JoinColumn(name = "market_id", nullable = false) 22 | private MarketEntity market; 23 | 24 | @ManyToOne(fetch = FetchType.LAZY) 25 | @JoinColumn(name = "company_id", nullable = false) 26 | private CompanyEntity company; 27 | 28 | @Column(nullable = false) 29 | private Long average; 30 | } 31 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/ChartRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.ChartEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.data.jpa.repository.Query; 6 | import org.springframework.data.repository.query.Param; 7 | 8 | import java.sql.Date; 9 | import java.time.LocalDate; 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | public interface ChartRepository extends JpaRepository { 14 | 15 | List findTop360ByCompanyIdAndDateGreaterThanEqual(Long companyId, LocalDate date); 16 | Optional findByCompanyIdAndDate(Long companyId, LocalDate date); 17 | // 시작 날짜부터 360개의 주식 데이터를 얻을 수 있는 범위 확인용 18 | @Query(value = "SELECT distinct c.date FROM chart c WHERE c.date >= :date LIMIT :limitValue", nativeQuery = true) 19 | List getMarketDateByDateGreaterThanEqualAndLimit(@Param("date") LocalDate date, @Param("limitValue") Integer limitValue); 20 | // 뉴스 정보 구매를 위해 해당 종목의 평균가 계산 21 | @Query(value = "SELECT AVG(c.price_end) FROM chart c WHERE c.date >= :start AND c.date <= :end AND c.company_id = :comapny", nativeQuery = true) 22 | Optional getAvgPriceEndByDateGreaterThanEqualAndDateLessThanEqualAndCompany(@Param("start") LocalDate start, @Param("end") LocalDate end, @Param("comapny") Long company_id); 23 | 24 | List findAllByCompanyIdAndDateBetween(Long companyId, LocalDate startDate, LocalDate date); 25 | } 26 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/CompanyRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.CompanyEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface CompanyRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/DealStockRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.DealStockEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface DealStockRepository extends JpaRepository { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/ExchangeRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.ExchangeEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.time.LocalDate; 7 | import java.util.List; 8 | 9 | public interface ExchangeRepository extends JpaRepository { 10 | 11 | List findAllByNationalCodeAndDateBetween(String type, LocalDate startAt, LocalDate endAt); 12 | } 13 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/MarketRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.MarketEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.util.Optional; 7 | 8 | public interface MarketRepository extends JpaRepository { 9 | Optional findTopByOrderByCreatedAtDesc(); 10 | } 11 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/MaterialRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.MaterialEntity; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | import java.time.LocalDate; 7 | import java.util.List; 8 | 9 | public interface MaterialRepository extends JpaRepository { 10 | 11 | List findAllByStandardTypeAndDateBetween(String type, LocalDate startAt, LocalDate endAt); 12 | } 13 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/StockRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.dto.StockListResDto; 4 | import com.server.back.domain.stock.entity.MarketEntity; 5 | import com.server.back.domain.stock.entity.StockEntity; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | 8 | import java.time.LocalDateTime; 9 | import java.util.*; 10 | 11 | public interface StockRepository extends JpaRepository { 12 | 13 | List findTop4ByOrderByIdDesc(); 14 | 15 | List findByMarket_Id(Long marketId); 16 | } 17 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/repository/UserDealRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.repository; 2 | 3 | import com.server.back.domain.stock.entity.UserDealEntity; 4 | import com.server.back.domain.user.entity.UserEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.util.List; 8 | 9 | import java.util.Optional; 10 | import java.util.Set; 11 | 12 | public interface UserDealRepository extends JpaRepository { 13 | 14 | Optional findByUserIdAndStockId(Long userId, Long stockId); 15 | 16 | ListfindAllByUserAndStockMarketId(UserEntity user, Long marketId); 17 | 18 | List findAllByStockId(Long stockId); 19 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/stock/service/StockService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.stock.service; 2 | 3 | import com.server.back.domain.stock.dto.*; 4 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; 5 | 6 | import java.time.LocalDate; 7 | 8 | public interface StockService { 9 | 10 | StockInfoResDto getStockList(); 11 | 12 | void getStockChart(Long stockId); 13 | 14 | DealResDto buyStock(StockReqDto stockReqDto); 15 | 16 | DealResDto sellStock(StockReqDto stockReqDto); 17 | 18 | SseEmitter subscribe(); 19 | 20 | void schedularData(); 21 | 22 | void calRate(LocalDate gameDate); 23 | } 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/storage/controller/StorageController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.storage.controller; 2 | 3 | import com.server.back.common.code.dto.ResultDto; 4 | import com.server.back.domain.mypage.dto.MyAssetResDto; 5 | import com.server.back.domain.storage.dto.AuctionHistoryResDto; 6 | import com.server.back.domain.storage.service.StorageService; 7 | import io.swagger.annotations.Api; 8 | import io.swagger.annotations.ApiOperation; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import java.util.List; 14 | 15 | @RestController 16 | @RequestMapping("/storage") 17 | @RequiredArgsConstructor 18 | @Api(tags = "창고 API") 19 | public class StorageController { 20 | 21 | private final StorageService storageService; 22 | 23 | @GetMapping 24 | @ApiOperation(value = "창고에 있는 물품 리스트 반환") 25 | public ResponseEntity>> getStorageList(){ 26 | List storageResDto= storageService.getStorageList(); 27 | return ResponseEntity.ok(ResultDto.of(storageResDto)); 28 | 29 | } 30 | 31 | @PostMapping("/resale/{myAssetId}") 32 | @ApiOperation(value = "창고에 있는 물품 되팔기") 33 | public ResponseEntity> createResale(@PathVariable Long myAssetId){ 34 | storageService.createResale(myAssetId); 35 | return ResponseEntity.ok().body(ResultDto.ofSuccess()); 36 | } 37 | 38 | @GetMapping("/auction/{myAssetId}") 39 | @ApiOperation(value = "해당 물품 경매 시세 반환") 40 | public ResponseEntity>> getQuote(@PathVariable Long myAssetId){ 41 | List quoteList=storageService.getQuote(myAssetId); 42 | return ResponseEntity.ok(ResultDto.of(quoteList)); 43 | } 44 | 45 | @GetMapping("/auction/history/{myAssetId}") 46 | @ApiOperation(value = "해당 물품 과거 경매 반환") 47 | public ResponseEntity>> getAuctionHistory(@PathVariable Long myAssetId){ 48 | List historyList=storageService.getAuctionHistory(myAssetId); 49 | return ResponseEntity.ok(ResultDto.of(historyList)); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/storage/dto/AuctionHistoryResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.storage.dto; 2 | 3 | import com.server.back.domain.auction.entity.AuctionEntity; 4 | import lombok.*; 5 | 6 | import java.time.LocalDate; 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | @Data 11 | @Builder 12 | public class AuctionHistoryResDto { 13 | 14 | private Long price; 15 | private LocalDate dealDate; 16 | 17 | public static AuctionHistoryResDto fromEntity(AuctionEntity auction){ 18 | return AuctionHistoryResDto.builder() 19 | .price(auction.getAuctionPrice()) 20 | .dealDate(auction.getUpdatedAt().toLocalDate()) 21 | .build(); 22 | } 23 | 24 | public static List fromEntityList(List auctionEntityList){ 25 | return auctionEntityList.stream().map(AuctionHistoryResDto::fromEntity).collect(Collectors.toList()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/storage/service/StorageService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.storage.service; 2 | 3 | import com.server.back.domain.mypage.dto.MyAssetResDto; 4 | import com.server.back.domain.storage.dto.AuctionHistoryResDto; 5 | 6 | import java.util.List; 7 | 8 | public interface StorageService { 9 | List getStorageList(); 10 | void createResale(Long myAssetId); 11 | 12 | List getQuote(Long myAssetId); 13 | 14 | List getAuctionHistory(Long myAssetId); 15 | } 16 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/controller/StoreController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.controller; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.common.code.dto.ResultDto; 5 | import com.server.back.domain.store.dto.AssetResDto; 6 | import com.server.back.domain.store.service.StoreService; 7 | import io.swagger.annotations.Api; 8 | import io.swagger.annotations.ApiOperation; 9 | import lombok.RequiredArgsConstructor; 10 | import org.springframework.http.HttpStatus; 11 | import org.springframework.http.ResponseEntity; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | @RestController 15 | @RequestMapping("/store") 16 | @RequiredArgsConstructor 17 | @Api(tags="상점(가챠) API") 18 | public class StoreController { 19 | private final StoreService service; 20 | 21 | 22 | @PostMapping("/level/{gotchaLevel}") 23 | @ApiOperation(value = "상점에서 갓챠를 통해 물품을 얻습니다.", notes = "") 24 | public ResponseEntity> gotchaAsset(@PathVariable String gotchaLevel){ 25 | 26 | AssetResDto respnoseDto=service.createGotcha(gotchaLevel); 27 | return ResponseEntity.status(HttpStatus.OK).body(ResultDto.of(respnoseDto)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/dto/AssetResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.dto; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.store.entity.AssetEntity; 5 | import lombok.*; 6 | 7 | @Data 8 | @Builder 9 | public class AssetResDto { 10 | private Long assetId; 11 | private String assetName; 12 | private AssetLevelType assetLevel; 13 | private String assetCategory; 14 | private String assetNameKor; 15 | 16 | public static AssetResDto fromEntity(AssetEntity asset){ 17 | return AssetResDto.builder() 18 | .assetId(asset.getId()) 19 | .assetName(asset.getAssetName()) 20 | .assetLevel(asset.getAssetLevel()) 21 | .assetCategory(asset.getCategory()) 22 | .assetNameKor(asset.getAssetNameKor()) 23 | .build(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/entity/AssetEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.entity; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import lombok.*; 5 | 6 | import javax.persistence.*; 7 | 8 | @Entity 9 | @Table(name="asset") 10 | @Getter 11 | @Builder 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | public class AssetEntity { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | private Long id; 18 | 19 | @Column(nullable = false) 20 | private String category; 21 | @Enumerated(EnumType.STRING) 22 | @Column(nullable = false) 23 | private AssetLevelType assetLevel; 24 | 25 | @Column(nullable = false,unique = true) 26 | private String assetName; 27 | 28 | @Column(nullable = false) 29 | private String assetNameKor; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/entity/AssetPriceEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.entity; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import lombok.*; 5 | 6 | import javax.persistence.*; 7 | 8 | @Entity 9 | @Builder 10 | @Table(name="asset_price") 11 | @Getter 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | @AllArgsConstructor 14 | public class AssetPriceEntity { 15 | @Id 16 | @GeneratedValue(strategy = GenerationType.IDENTITY) 17 | private Long id; 18 | 19 | @Enumerated(EnumType.STRING) 20 | @Column(nullable = false) 21 | private AssetLevelType assetLevel; 22 | 23 | @Column(nullable = false) 24 | private Long price; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/entity/UserAssetEntity.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.entity; 2 | 3 | import com.server.back.common.code.commonCode.IsAuctioned; 4 | import com.server.back.common.code.commonCode.IsDeleted; 5 | import com.server.back.common.code.commonCode.IsInRespository; 6 | import com.server.back.domain.user.entity.UserEntity; 7 | import lombok.AccessLevel; 8 | import lombok.AllArgsConstructor; 9 | import lombok.Getter; 10 | import lombok.NoArgsConstructor; 11 | import lombok.experimental.SuperBuilder; 12 | 13 | import javax.persistence.*; 14 | 15 | @Entity 16 | @Table(name="user_asset") 17 | @Getter 18 | @SuperBuilder 19 | @Inheritance(strategy = InheritanceType.JOINED) 20 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 21 | @AllArgsConstructor 22 | public class UserAssetEntity { 23 | @Id 24 | @GeneratedValue(strategy = GenerationType.IDENTITY) 25 | private Long id; 26 | 27 | @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY) 28 | @JoinColumn(name="asset_id",nullable = false) 29 | private AssetEntity asset; 30 | 31 | @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY) 32 | @JoinColumn(name="user_id",nullable = false) 33 | private UserEntity user; 34 | 35 | @Enumerated(EnumType.STRING) 36 | @Column(nullable = false) 37 | private IsDeleted isDeleted; 38 | 39 | @Enumerated(EnumType.STRING) 40 | @Column(nullable = false) 41 | private IsInRespository isInRepository; 42 | 43 | @Enumerated(EnumType.STRING) 44 | @Column(nullable = false) 45 | private IsAuctioned isAuctioned; 46 | 47 | //룸에 배치 or repository에 넣기 48 | public void update(IsInRespository isInRespository){ 49 | this.isInRepository=isInRespository; 50 | } 51 | 52 | //경매장에 내놓을 때 or 취소할 때 53 | public void update(IsAuctioned isAuctioned){ 54 | this.isAuctioned=isAuctioned; 55 | } 56 | 57 | //되팔기 58 | public void update(){ 59 | this.isDeleted=IsDeleted.Y; 60 | } 61 | 62 | //경매 참여했을 때 63 | public void update(UserEntity user){ 64 | this.user=user; 65 | this.isAuctioned=IsAuctioned.N; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/entity/UserAssetLocation.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.entity; 2 | 3 | import lombok.*; 4 | import lombok.experimental.SuperBuilder; 5 | 6 | import javax.persistence.*; 7 | 8 | @Entity 9 | @Table(name="user_asset_location") 10 | @Getter 11 | @SuperBuilder 12 | @NoArgsConstructor(access = AccessLevel.PROTECTED) 13 | public class UserAssetLocation extends UserAssetEntity { 14 | 15 | @Column(nullable = false) 16 | private float posX; 17 | 18 | @Column(nullable = false) 19 | private float posY; 20 | 21 | @Column(nullable = false) 22 | private float posZ; 23 | 24 | @Column(nullable = false) 25 | private float rotX; 26 | 27 | @Column(nullable = false) 28 | private float rotY; 29 | 30 | @Column(nullable = false) 31 | private float rotZ; 32 | 33 | public void init(){ 34 | this.posX=0F; 35 | this.posY=0F; 36 | this.posZ=-200F; 37 | this.rotX=0F; 38 | this.rotY=0F; 39 | this.rotZ=0F; 40 | } 41 | 42 | public void initZero(){ 43 | this.posX=0F; 44 | this.posY=0F; 45 | this.posZ=0F; 46 | this.rotX=0F; 47 | this.rotY=0F; 48 | this.rotZ=0F; 49 | } 50 | 51 | 52 | public void update(float posX,float posY,float posZ,float rotX,float rotY,float rotZ){ 53 | this.posX=posX; 54 | this.posY=posY; 55 | this.posZ=posZ; 56 | this.rotX=rotX; 57 | this.rotY=rotY; 58 | this.rotZ=rotZ; 59 | } 60 | 61 | public void update(float rotZ){ 62 | this.rotZ=rotZ; 63 | } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/repository/AssetPriceRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.repository; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.store.entity.AssetPriceEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import java.util.Optional; 8 | 9 | public interface AssetPriceRepository extends JpaRepository { 10 | OptionalfindByAssetLevel(AssetLevelType assetLevelType); 11 | } 12 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/repository/AssetRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.repository; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.store.entity.AssetEntity; 5 | import io.lettuce.core.dynamic.annotation.Param; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.data.jpa.repository.Query; 8 | 9 | import java.util.List; 10 | 11 | public interface AssetRepository extends JpaRepository { 12 | @Query(value = "SELECT * FROM asset WHERE asset_level = :assetLevelType ORDER BY RAND() LIMIT 1", nativeQuery = true) 13 | AssetEntity findByAssetLevelAndLimit(@Param("assetLevelType") String assetLevelType); 14 | List findByAssetLevel(AssetLevelType assetLevel); 15 | List findByCategory(String category); 16 | List findByAssetLevelAndCategory(AssetLevelType assetLevel, String category); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/repository/UserAssetLocationRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.repository; 2 | 3 | import com.server.back.common.code.commonCode.IsAuctioned; 4 | import com.server.back.common.code.commonCode.IsDeleted; 5 | import com.server.back.common.code.commonCode.IsInRespository; 6 | import com.server.back.domain.store.entity.UserAssetLocation; 7 | import com.server.back.domain.user.entity.UserEntity; 8 | import org.springframework.data.jpa.repository.JpaRepository; 9 | 10 | import java.util.List; 11 | import java.util.Optional; 12 | 13 | public interface UserAssetLocationRepository extends JpaRepository { 14 | Optional findByIdAndIsDeletedAndIsInRepositoryAndIsAuctioned(Long id, IsDeleted isDeleted, IsInRespository isInRespository, IsAuctioned isAuctioned); 15 | Optional findByIdAndIsDeleted(Long id, IsDeleted isDeleted); 16 | List findAllByUserAndIsDeletedAndIsAuctionedAndIsInRepository(UserEntity user,IsDeleted isDeleted,IsAuctioned isAuctioned,IsInRespository isInRespository); 17 | } 18 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/repository/UserAssetRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.repository; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.common.code.commonCode.IsDeleted; 5 | import com.server.back.common.code.commonCode.IsInRespository; 6 | import com.server.back.domain.store.entity.UserAssetEntity; 7 | import com.server.back.domain.user.entity.UserEntity; 8 | import org.springframework.data.jpa.repository.JpaRepository; 9 | import org.springframework.data.jpa.repository.Query; 10 | import org.springframework.data.repository.query.Param; 11 | 12 | import java.util.List; 13 | import java.util.Optional; 14 | 15 | public interface UserAssetRepository extends JpaRepository { 16 | ListfindByUserAndIsInRepositoryAndIsDeleted(UserEntity user, IsInRespository isInRespository, IsDeleted isDeleted); 17 | List findByUserAndIsDeleted(UserEntity user, IsDeleted isDeleted); 18 | Optional findByIdAndIsDeleted(Long userAssetId,IsDeleted isDeleted); 19 | 20 | @Query("SELECT COUNT(u) FROM UserAssetEntity u WHERE u.user.id = :userId AND u.isDeleted = :isDeleted AND u.asset.assetLevel = :assetLevel") 21 | Optional countByUserIdAndIsDeletedAndAssetLevel(@Param("userId") Long userId, @Param("isDeleted") IsDeleted isDeleted, @Param("assetLevel") AssetLevelType assetLevel); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/store/service/StoreService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.store.service; 2 | 3 | import com.server.back.common.code.commonCode.AssetLevelType; 4 | import com.server.back.domain.store.dto.AssetResDto; 5 | 6 | public interface StoreService { 7 | AssetResDto createGotcha(String gotchaLevel); 8 | } 9 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.controller; 2 | 3 | 4 | import com.server.back.common.code.dto.ResultDto; 5 | import com.server.back.domain.user.dto.LoginReqDto; 6 | import com.server.back.domain.user.dto.LoginResDto; 7 | import com.server.back.domain.user.service.LoginService; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiOperation; 10 | import lombok.RequiredArgsConstructor; 11 | import lombok.extern.slf4j.Slf4j; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.web.bind.annotation.*; 14 | 15 | import javax.servlet.http.HttpServletResponse; 16 | import java.util.Map; 17 | 18 | @Slf4j 19 | @RestController 20 | @RequiredArgsConstructor 21 | @Api(tags = "유저 로그인 API") 22 | public class LoginController { 23 | 24 | private final LoginService loginService; 25 | 26 | @PostMapping("/login") 27 | @ApiOperation(value = "로그인합니다.", notes = "") 28 | public ResponseEntity> login(@RequestBody LoginReqDto loginReqDto, HttpServletResponse response) { 29 | LoginResDto loginResDto = loginService.login(loginReqDto, response); 30 | 31 | return ResponseEntity.ok().body(ResultDto.of(loginResDto)); 32 | } 33 | 34 | 35 | @PostMapping("/refresh") 36 | @ApiOperation(value = "엑세스 토큰을 재발급합니다.", notes = "") 37 | public ResponseEntity> createAccessToken(@RequestHeader Map loginRequestHeader, HttpServletResponse response) { 38 | LoginResDto loginResDto = loginService.createAccessToken(loginRequestHeader, response); 39 | 40 | return ResponseEntity.ok().body(ResultDto.of(loginResDto)); 41 | } 42 | 43 | 44 | @GetMapping("/logout/redirect") 45 | @ApiOperation(value = "로그아웃합니다.", notes = "") 46 | public ResponseEntity> logoutPost(@RequestHeader Map logoutRequestHeader) { 47 | loginService.deleteAccessToken(logoutRequestHeader); 48 | 49 | return ResponseEntity.ok().body(ResultDto.ofSuccess()); 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/LoginReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * 로그인 9 | */ 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class LoginReqDto { 14 | private String account; 15 | private String password; 16 | } 17 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/LoginResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | 8 | @Data 9 | @Builder 10 | public class LoginResDto { 11 | private String accessToken; 12 | private String refreshToken; 13 | private String nickname; 14 | 15 | public static LoginResDto fromEntity(String accessToken, String refreshToken, String nickname) { 16 | return LoginResDto.builder() 17 | .accessToken(accessToken) 18 | .refreshToken(refreshToken) 19 | .nickname(nickname) 20 | .build(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/UserInfoLoginResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder 9 | public class UserInfoLoginResDto { 10 | private String nickname; 11 | private Long currentMoney; 12 | private Float totalStockReturn; 13 | private String profileImagePath; 14 | 15 | public static UserInfoLoginResDto fromEntity(UserEntity user, Float totalStockReturn) { 16 | return UserInfoLoginResDto.builder() 17 | .nickname(user.getNickname()) 18 | .currentMoney(user.getCurrentMoney()) 19 | .totalStockReturn(totalStockReturn) 20 | .profileImagePath(user.getProfileImagePath()) 21 | .build(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/UserInfoReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | import org.springframework.format.annotation.DateTimeFormat; 8 | 9 | import java.time.LocalDate; 10 | 11 | 12 | @Data 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class UserInfoReqDto { 16 | @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) 17 | private LocalDate time; 18 | } 19 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/UserInfoResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | @Data 8 | @Builder 9 | public class UserInfoResDto { 10 | private String nickname; 11 | private String profileImagePath; 12 | private String introduction; 13 | private Long totalCash; 14 | 15 | public static UserInfoResDto fromEntity(UserEntity user, Long totalCash) { 16 | return UserInfoResDto.builder() 17 | .nickname(user.getNickname()) 18 | .profileImagePath(user.getProfileImagePath()) 19 | .introduction(user.getIntroduction()) 20 | .totalCash(totalCash) 21 | .build(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/UserResDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | 7 | import java.util.List; 8 | import java.util.stream.Collectors; 9 | 10 | @Data 11 | @Builder 12 | public class UserResDto { 13 | private String account; 14 | private String nickname; 15 | private String profileImagePath; 16 | 17 | public static UserResDto fromEntity(UserEntity user) { 18 | return UserResDto.builder() 19 | .account(user.getAccount()) 20 | .nickname(user.getNickname()) 21 | .profileImagePath(user.getProfileImagePath()) 22 | .build(); 23 | } 24 | 25 | public static List fromEnityList( List userList ){ 26 | return userList.stream().map(UserResDto::fromEntity).collect(Collectors.toList()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/UsersModifyReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * 회원 정보 수정 11 | */ 12 | @Builder 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class UsersModifyReqDto { 17 | private String nickname; 18 | private String password; 19 | private String introduction; 20 | 21 | public UserEntity toEntity(UserEntity user) { 22 | return UserEntity.builder() 23 | .id(user.getId()) 24 | .account(user.getAccount()) 25 | .nickname(nickname) 26 | .password(password) 27 | .profileImagePath(user.getProfileImagePath()) 28 | .introduction(introduction) 29 | .isDeleted(user.getIsDeleted()) 30 | .currentMoney(user.getCurrentMoney()) 31 | .role(user.getRole()) 32 | .build(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/dto/UsersRegisterReqDto.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.dto; 2 | 3 | import com.server.back.domain.user.entity.UserEntity; 4 | import lombok.*; 5 | 6 | /** 7 | * 회원가입 요청 8 | */ 9 | @Builder 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class UsersRegisterReqDto { 14 | private String account; 15 | private String nickname; 16 | private String password; 17 | 18 | public UserEntity toEntity(String profileImagePath) { 19 | return UserEntity.builder() 20 | .account(account) 21 | .nickname(nickname) 22 | .password(password) 23 | .profileImagePath(profileImagePath) 24 | .build(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.repository; 2 | 3 | import com.server.back.common.code.commonCode.IsDeleted; 4 | import com.server.back.domain.user.entity.UserEntity; 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | import org.springframework.data.jpa.repository.Query; 7 | import org.springframework.data.repository.query.Param; 8 | 9 | import java.util.List; 10 | import java.util.Optional; 11 | 12 | public interface UserRepository extends JpaRepository { 13 | Optional findByIdAndIsDeleted(Long id, IsDeleted isDeleted); 14 | 15 | Optional findByAccount(String account); 16 | 17 | Optional findByAccountAndIsDeleted(String account, IsDeleted isDeleted); 18 | 19 | Optional findByNicknameAndIsDeleted(String nickname, IsDeleted isDeleted); 20 | 21 | List findByAccountContainingAndIsDeletedOrNicknameContainingAndIsDeleted(String accountSearch,IsDeleted isDeletedA, String nicknameSearch,IsDeleted isDeleted); 22 | 23 | List findByNicknameContaining(String keyword); 24 | List findByAccountContaining(String keyword); 25 | 26 | @Query(value = "SELECT * FROM user_table WHERE id <> :excludeId AND is_deleted = 'N' ORDER BY RAND() LIMIT 1", nativeQuery = true) 27 | Optional findRandomUserExcludingAndIsDeleted(@Param("excludeId") Long excludeId); 28 | 29 | List findAllByIsDeleted(IsDeleted isDeleted); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/service/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.service; 2 | 3 | import com.server.back.common.code.commonCode.IsDeleted; 4 | import com.server.back.domain.user.entity.UserEntity; 5 | import com.server.back.domain.user.repository.UserRepository; 6 | import lombok.RequiredArgsConstructor; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.security.core.userdetails.UserDetails; 9 | import org.springframework.security.core.userdetails.UserDetailsService; 10 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.Optional; 14 | 15 | 16 | @Slf4j 17 | @Service 18 | @RequiredArgsConstructor 19 | public class CustomUserDetailsService implements UserDetailsService { 20 | 21 | private final UserRepository userRepository; 22 | 23 | 24 | @Override 25 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 26 | // log.info("[loadUserByUsername] username: {}", username); 27 | 28 | Optional user = userRepository.findByIdAndIsDeleted(Long.parseLong(username), IsDeleted.N); 29 | if (user.isEmpty()) { 30 | throw new UsernameNotFoundException(username); 31 | } 32 | return user.get(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/service/LoginService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.service; 2 | 3 | import com.server.back.domain.user.dto.LoginReqDto; 4 | import com.server.back.domain.user.dto.LoginResDto; 5 | 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.util.Map; 8 | 9 | public interface LoginService { 10 | LoginResDto login(LoginReqDto loginReqDto, HttpServletResponse response); 11 | 12 | LoginResDto createAccessToken(Map loginRequestHeader, HttpServletResponse response); 13 | 14 | void deleteAccessToken(Map logoutRequestHeader); 15 | } 16 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/domain/user/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.server.back.domain.user.service; 2 | 3 | import com.server.back.domain.user.dto.*; 4 | import com.server.back.domain.user.entity.UserEntity; 5 | 6 | import java.util.List; 7 | 8 | public interface UserService { 9 | 10 | UserEntity getUserById(Long id); 11 | UserEntity getUserByNickname(String nickname); 12 | 13 | void createUser(UsersRegisterReqDto usersRegisterReqDto); 14 | 15 | UserInfoLoginResDto getLoginUser(); 16 | 17 | Boolean checkAccount(String account); 18 | 19 | Boolean checkNickname(String nickname); 20 | 21 | void updateUser(UsersModifyReqDto usersModifyReqDto); 22 | 23 | void deleteUser(); 24 | 25 | List getUserList(String search); 26 | 27 | UserResDto getUserRandom(); 28 | 29 | UserInfoResDto getUser(String nickname); 30 | } 31 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.server.back.exception; 2 | 3 | 4 | import lombok.AllArgsConstructor; 5 | import lombok.Getter; 6 | 7 | 8 | @Getter 9 | @AllArgsConstructor 10 | public class CustomException extends RuntimeException { 11 | 12 | private final ErrorCode errorCode; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/exception/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.server.back.exception; 2 | 3 | 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import org.springframework.http.HttpStatus; 7 | 8 | import static org.springframework.http.HttpStatus.*; 9 | 10 | 11 | @Getter 12 | @RequiredArgsConstructor 13 | public enum ErrorCode { 14 | 15 | /* 필요한 ERROR CODE 아래 처럼 작성 및 추가하기 */ 16 | ERROR_NAME(NOT_FOUND, "에러 메세지 입니다") 17 | 18 | /* 409 CONFLICT : Resource 의 현재 상태와 충돌. 보통 중복된 데이터 존재 */, 19 | DUPLICATE_RESOURCE(CONFLICT, "데이터가 이미 존재합니다"), 20 | MISMATCH_REQUEST(BAD_REQUEST, "데이터 간 의미가 어긋납니다 (예: 공통코드와 대응되는 데이터)"), 21 | 22 | /* 400 BAD REQUEST : 잘못된 요청. 입력된 데이터에 문제가 있음 */ 23 | PASSWORD_NOT_MATCH(BAD_REQUEST, "패스워드가 일치하지 않습니다."), 24 | LACK_OF_MONEY(BAD_REQUEST, "잔액이 부족합니다."), 25 | FULL_OF_MONEY(BAD_REQUEST,"지갑이 꽉찼습니다."), 26 | LACK_OF_STOCK(BAD_REQUEST,"매도할 주식이 없습니다."), 27 | IMPOSSIBLE_FUNCTION(BAD_REQUEST, "가입 후 3시간 뒤 이용할 수 있는 기능입니다."), 28 | IMPOSSIBLE_TRANSFER(BAD_REQUEST, "가입 후 3시간이 지난 사용자에게 송금할 수 있습니다."), 29 | 30 | 31 | /* 401 UNAUTHORIZED : 권한 인증 문제. JWT 토큰과 관련된 에러 */ 32 | UNAUTHORIZED_USER(UNAUTHORIZED, "권한이 허용되지 않은 유저입니다."), 33 | 34 | TOKEN_ERROR(UNAUTHORIZED, "토큰에 문제가 있습니다."), 35 | ACCESS_TOKEN_EXPIRED(UNAUTHORIZED, "토큰의 유효기간이 만료되었습니다."), 36 | ACCESS_TOKEN_NOT_FOUND(UNAUTHORIZED, "액세스 토큰이 존재하지 않습니다."), 37 | REFRESH_TOKEN_NOT_FOUND(UNAUTHORIZED, "리프레시 토큰이 존재하지 않습니다."), 38 | ACCESS_TOKEN_ERROR(UNAUTHORIZED, "액세스 토큰에 문제가 있습니다."), 39 | REFRESH_TOKEN_ERROR(UNAUTHORIZED, "리프레시 토큰에 문제가 있습니다."), 40 | 41 | /* 403 FORBIDDEN : 접근 권한 없음 */ 42 | NO_ACCESS(FORBIDDEN, "페이지에 대한 접근 권한이 없습니다."), 43 | 44 | /* 404 NOT_FOUND : 대상이 존재하지 않음 */ 45 | ENTITY_NOT_FOUND(NOT_FOUND, "대상이 존재하지 않습니다."), 46 | SOLD_ENTITY(NOT_FOUND, "판매 완료된 상품입니다."), 47 | CANCELED_ENTITY(NOT_FOUND, "판매 취소된 상품입니다."), 48 | USER_NOT_FOUND(NOT_FOUND, "회원이 존재하지 않습니다."); 49 | 50 | /* 500 INTERNAL_SERVER_ERROR : 서버 오류 - 정말 필요한 거 외엔 되도록 쓰지 않는 걸 권장*/ 51 | 52 | 53 | private final HttpStatus httpStatus; 54 | private final String message; 55 | } 56 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/exception/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.server.back.exception; 2 | 3 | 4 | import com.server.back.common.code.dto.ResultEnum; 5 | import lombok.Builder; 6 | import lombok.Getter; 7 | import org.springframework.http.ResponseEntity; 8 | 9 | import java.time.LocalDateTime; 10 | 11 | 12 | @Getter 13 | @Builder 14 | public class ErrorResponse { 15 | 16 | private final LocalDateTime timestamp = LocalDateTime.now(); 17 | private final int status; 18 | private final String error; 19 | private final String code; 20 | private final String message; 21 | private final ResultEnum result = ResultEnum.FAIL; 22 | 23 | 24 | public static ResponseEntity toResponseEntity(ErrorCode errorCode) { 25 | return ResponseEntity 26 | .status(errorCode.getHttpStatus()) 27 | .body(ErrorResponse.builder() 28 | .status(errorCode.getHttpStatus().value()) 29 | .error(errorCode.getHttpStatus().name()) 30 | .code(errorCode.name()) 31 | .message(errorCode.getMessage()) 32 | .build() 33 | ); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /back-server/src/main/java/com/server/back/exception/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.server.back.exception; 2 | 3 | 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.hibernate.exception.ConstraintViolationException; 6 | import org.springframework.dao.DataIntegrityViolationException; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.ExceptionHandler; 9 | import org.springframework.web.bind.annotation.RestControllerAdvice; 10 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 11 | 12 | import static com.server.back.exception.ErrorCode.DUPLICATE_RESOURCE; 13 | 14 | 15 | @Slf4j 16 | @RestControllerAdvice 17 | public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { 18 | 19 | /** 20 | * hibernate 관련 Exception 21 | */ 22 | @ExceptionHandler(value = { ConstraintViolationException.class, DataIntegrityViolationException.class }) 23 | protected ResponseEntity handleDataException() { 24 | log.error("handleDataException throw Exception : {}", DUPLICATE_RESOURCE); 25 | return ErrorResponse.toResponseEntity(DUPLICATE_RESOURCE); 26 | } 27 | 28 | 29 | /** 30 | * 사용 방법 31 | * 로직 내에서 throw new CustomException(ErrorCode.enum); 32 | */ 33 | @ExceptionHandler(value = { CustomException.class }) 34 | protected ResponseEntity handleCustomException(CustomException exception) { 35 | log.error("handleCustomException throw CustomException : {}", exception.getErrorCode()); 36 | return ErrorResponse.toResponseEntity(exception.getErrorCode()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /back-server/src/test/java/com/server/back/BackApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.server.back; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class BackApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /data-crawling/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /data-crawling/README.md: -------------------------------------------------------------------------------- 1 | # data_crawling 2 | 3 | 모두의 주식용 데이터 수집 4 | 5 | ## 버전 6 | 7 | - conda 가상 환경 8 | - Python : 3.10.9 9 | 10 | ## 설치 순서 11 | 12 | - conda 가상 환경 설치 13 | 14 | ``` 15 | conda create --name [env-name] --file environments.txt 16 | ``` 17 | 18 | - requirements 설치 19 | 20 | ``` 21 | pip install -r requirements.txt 22 | ``` 23 | -------------------------------------------------------------------------------- /data-crawling/data/exchange/data(cur_20141031).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/exchange/data(cur_20141031).p -------------------------------------------------------------------------------- /data-crawling/data/exchange/data(cur_20180831).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/exchange/data(cur_20180831).p -------------------------------------------------------------------------------- /data-crawling/data/exchange/data(cur_20211028).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/exchange/data(cur_20211028).p -------------------------------------------------------------------------------- /data-crawling/data/exchange/data(cur_20221231).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/exchange/data(cur_20221231).p -------------------------------------------------------------------------------- /data-crawling/data/material/data(domestic_gold_230414).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/material/data(domestic_gold_230414).p -------------------------------------------------------------------------------- /data-crawling/data/material/data(national_gold_230414).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/material/data(national_gold_230414).p -------------------------------------------------------------------------------- /data-crawling/data/material/data(oil_gsl_230414).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/material/data(oil_gsl_230414).p -------------------------------------------------------------------------------- /data-crawling/data/material/data(oil_lo_230414).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/material/data(oil_lo_230414).p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_LG전자_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_LG전자_230420).p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_LG화학_230418)_real_final_final.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_LG화학_230418)_real_final_final.p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_SK텔레콤_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_SK텔레콤_230420).p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_naver_230417)_real_final_final.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_naver_230417)_real_final_final.p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_녹십자_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_녹십자_230420).p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_롯데케미칼_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_롯데케미칼_230420).p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_삼성전자_230418)_real_final_final.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_삼성전자_230418)_real_final_final.p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_셀트리온_230419)_2.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_셀트리온_230419)_2.p -------------------------------------------------------------------------------- /data-crawling/data/news/data(news_셀트리온_230419)_real_final_final.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/news/data(news_셀트리온_230419)_real_final_final.p -------------------------------------------------------------------------------- /data-crawling/data/nnp/nnp_company.csv: -------------------------------------------------------------------------------- 1 | ,nnp,after 2 | 5455,네이버,G IT 3 | 12400,NAVER,G IT 4 | 951,LINE,G SNS 5 | 5686,네이버 클라우드,G 인프라 6 | 11972,한게임,G Game 7 | 11696,LG전자,B 전자 8 | 12405,LG 전자,B 전자 9 | 4099,LG이노텍,B 소재·부품기업 10 | 1050,LG CNS,B IT 11 | 3834,LG유플러스,B 통신 12 | 6607,LGU+,B 통신 13 | 7329,LG상사,B 상사 14 | 11379,LG디스플레이, B 디스플레이 15 | 9687,LG생활건강,B 생활용품 16 | 9896,LG엔시스,B 인프라 17 | 8303,LG생명과학,B 화학 18 | 7381,LG화학,B 화학 19 | 12404,LG 화학,B 화학 20 | 7132,LG그룹,B 그룹 21 | 1168,LG,B 그룹 22 | 6616,엘지,B 그룹 23 | 1504,SK텔레콤,I IT 24 | 12419,SK 텔레콤,I IT 25 | 12420,SK T,I IT 26 | 12421,SKT,I IT 27 | 233,SK하이닉스,I 반도체 28 | 686,SK네트웍스,I 네트워크 29 | 2088,SKIET,I 테크 30 | 5460,SK케미칼,I 화학 31 | 2603,SK이노베이션,I 화학 32 | 3883,SK에너지,I 화학 33 | 4799,SK커뮤니케이션즈,I SNS 34 | 10958,SKB,I 유선 35 | 5703,SK브로드,I 유선 36 | 6347,SK플래닛,I 데이터 37 | 6946,SKC&C,I IT서비스 38 | 8373,11번가,I 쇼핑 39 | 11537,SK증권,I 증권 40 | 11035,SK그룹,I 그룹 41 | 8084,SK,I 그룹 42 | 2346,삼성전자,A 전자 43 | 12401,삼성 전자,A 전자 44 | 4930,삼성SDI,A 에너지 45 | 2341,SDS,A IT 46 | 11688,삼성중공업,A 중공업 47 | 9992,삼성화재,A 보험 48 | 9952,삼성제약,A 생명 49 | 5590,삼성바이오로직스,A 생명 50 | 1566,삼성메디슨,A 생명 51 | 4037,삼성물산,A 건설 52 | 2359,삼성증권,A 금융 53 | 2090,삼성카드,A 금융 54 | 2428,삼성엔지니어링,A EPC 55 | 4965,삼성전기,A 반도체 56 | 12402,SAMSUNG,A 그룹 57 | 12403,SAM SUMG,A 그룹 58 | 10833,삼성그룹,A 그룹 59 | 4280,삼성,A 그룹 60 | 4591,롯데케미칼,D 화학 61 | 12417,롯데 케미칼,D 화학 62 | 12418,호남석유화학,D 화학(전) 63 | 3127,롯데정밀화학,D 에너지 64 | 1672,롯데카드,D 카드 65 | 4210,롯데캐피탈,D 캐피탈 66 | 4825,롯데제과,D 식품 67 | 8664,롯데건설,D 건설 68 | 8872,롯데홀딩스,D 지주회사 69 | 9210,롯데백화점,D 백화점 70 | 9550,롯데칠성음료,D 음료 71 | 10355,롯데시네마,D 영화 72 | 10664,롯데월드,D 월드 73 | 12388,롯데닷컴,D 쇼핑 74 | 10319,롯데정보통신,D IT 75 | 7345,롯데 자이언츠,D 야구 76 | 7345,롯데자이언츠,D 야구 77 | 1584,롯데그룹,D 그룹 78 | 10318,롯데,D 그룹 79 | 767,녹십자,H 생명 80 | 12406,GC녹십자웰빙,H 생명 81 | 12407,GC녹십자,H 생명 82 | 12408,녹십자생명,H 생명 83 | 12409,녹십자웰빙,H 생명 84 | 12410,GC녹십자엠에스,H 생명 85 | 12411,GC녹십자셀,H 생명 86 | 12412,GC녹십자랩셀,H 생명 87 | 12413,GC녹십자MS,H 생명 88 | 12414,녹십자엠에스,H 생명 89 | 12415,녹십자MS,H 생명 90 | 2193,셀트리온,C 생명 91 | 12416,셀트리온GSC,C 생명 -------------------------------------------------------------------------------- /data-crawling/data/nnp/nnp_product.csv: -------------------------------------------------------------------------------- 1 | ,nnp 2 | 37,VIBE,G 음악 3 | 3761,쥬니어네이버,G 키즈 4 | 7105,네이버 지도,G 지도 5 | 6 | 8423,LG 마그나,B 스마트폰 M 7 | 9629,LG G,B 스마트폰 8 | 10028,옵티머스 패드,B 패드 9 | 3416,옵티머스패드,B 패드 10 | 10223,코드제로 T9,B 청소기 11 | 129,넥서스,B 스마트폰 N 12 | 628,K10,B 스마트폰 K10 13 | 1044,LG K,B 스마트폰 K 14 | 2909,LG 옵티머스 3D,B 스마트폰 3D 15 | 3414,LG X,B 스마트폰 X 16 | 3531,옵티머스,B 스마트폰 17 | 5665,G8,B 스마트폰 G8 18 | 5666,G7,B 스마트폰 G7 19 | 5667,G6,B 스마트폰 G6 20 | 5668,G5,B 스마트폰 G5 21 | 5669,G4,B 스마트폰 G4 22 | 5670,G3,B 스마트폰 G3 23 | 6425,LG V,B 스마트폰 V 24 | 25 | 11458,NUGU,I 인공지능 26 | 2811,티맵, I 지도 27 | 2812,T MAP, I 지도 28 | 29 | 6378,타이젠,A OS 30 | 10323,T9000,A 냉장고 T 31 | 9749,삼성 제트,A 청소기 32 | 297,빅스비,A 인공지능 33 | 7590,SSAFY,A 교육 34 | 7591,삼성청년SW아카데미,A 교육 35 | 7594,삼성 청년 소프트웨어 아카데미,A 교육 36 | 11582,삼성 페이,A 결제 37 | 4138,갤럭시,A 스마트폰 38 | 5847,삼성 기어 VR,A VR 39 | 195,엑시노트,A 프로세서 40 | 195,엑시노스,A 프로세서 41 | 196,Z3,A 스마트폰 Z 42 | 300,M7,A 모니터 -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_LG전자_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_LG전자_230420).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_LG화학_230418).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_LG화학_230418).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_SK텔레콤_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_SK텔레콤_230420).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_네이버_230416).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_네이버_230416).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_녹십자_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_녹십자_230420).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_롯데케미칼_230420).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_롯데케미칼_230420).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_삼성전자_230418).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_삼성전자_230418).p -------------------------------------------------------------------------------- /data-crawling/data/stock/data(stock_셀트리온_230418).p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/data-crawling/data/stock/data(stock_셀트리온_230418).p -------------------------------------------------------------------------------- /data-crawling/db/from-currency to-exchange 변환.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO exchange (national_code, date, price) 2 | ( 3 | SELECT "미국", cur_date, cur_rate 4 | FROM currency 5 | WHERE cur_name = "달러" 6 | ); 7 | 8 | INSERT INTO exchange (national_code, date, price) 9 | ( 10 | SELECT "유럽 연합", cur_date, cur_rate 11 | FROM currency 12 | WHERE cur_name = "유로" 13 | ); 14 | 15 | INSERT INTO exchange (national_code, date, price) 16 | ( 17 | SELECT "일본", cur_date, cur_rate 18 | FROM currency 19 | WHERE cur_name = "100엔" 20 | ); -------------------------------------------------------------------------------- /data-crawling/db/from-material to-market 변환.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO market (date, standard_type, price) 2 | ( 3 | SELECT material_date, 4 | "유가", 5 | ROUND(AVG(material_rate), 2) 6 | FROM material 7 | WHERE material_name = "휘발유" OR material_name = "경유" 8 | GROUP BY material_date 9 | ); 10 | 11 | INSERT INTO market (date, standard_type, price) 12 | ( 13 | SELECT material_date, 14 | "금", 15 | material_rate 16 | FROM material 17 | WHERE material_name = "국내금(원/g)" 18 | GROUP BY material_date 19 | ); -------------------------------------------------------------------------------- /data-crawling/db/from-news_origin to-news 변환.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO news (company_id, date, content) 2 | ( 3 | SELECT 9, 4 | news_date, 5 | news_content 6 | FROM news_origin 7 | WHERE news_name="I IT" 8 | ); -------------------------------------------------------------------------------- /data-crawling/db/from-stock to-chart 변환.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM access_db.chart; 2 | 3 | INSERT INTO chart (price_before, price_end, date, company_id) 4 | ( 5 | SELECT stock_rate + IF(stock_state = "up", -stock_change, IF(stock_state = "down", stock_change, 0)), 6 | stock_rate, 7 | stock_date, 8 | 9 9 | FROM stock 10 | WHERE stock_name = "I IT" 11 | ); -------------------------------------------------------------------------------- /data-crawling/db/pk_init.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE [table] AUTO_INCREMENT=1; 2 | SET @COUNT = 0; 3 | UPDATE [table] SET [col_name] = @COUNT:=@COUNT+1; -------------------------------------------------------------------------------- /data-crawling/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==3.8.4 2 | aiosignal==1.3.1 3 | aniso8601==9.0.1 4 | asttokens==2.2.1 5 | async-timeout==4.0.2 6 | attrs==22.2.0 7 | backcall==0.2.0 8 | beautifulsoup4==4.11.2 9 | blis==0.7.9 10 | brotlipy==0.7.0 11 | catalogue==2.0.8 12 | click==8.1.3 13 | comm==0.1.2 14 | confection==0.0.4 15 | cymem==2.0.7 16 | debugpy==1.6.6 17 | decorator==5.1.1 18 | executing==1.2.0 19 | filelock==3.9.0 20 | Flask==2.2.3 21 | Flask-Cors==3.0.10 22 | flask-restx==1.1.0 23 | frozenlist==1.3.3 24 | gdown==4.6.4 25 | ipykernel==6.21.3 26 | ipython==8.11.0 27 | itsdangerous==2.1.2 28 | jedi==0.18.2 29 | Jinja2==3.1.2 30 | JPype1==1.4.1 31 | jsonschema==4.17.3 32 | jupyter_client==8.0.3 33 | jupyter_core==5.3.0 34 | ko-core-news-lg @ https://github.com/explosion/spacy-models/releases/download/ko_core_news_lg-3.5.0/ko_core_news_lg-3.5.0-py3-none-any.whl 35 | konlpy==0.6.0 36 | langcodes==3.3.0 37 | lxml==4.9.2 38 | MarkupSafe==2.1.2 39 | matplotlib-inline==0.1.6 40 | multidict==6.0.4 41 | murmurhash==1.0.9 42 | nest-asyncio==1.5.6 43 | numpy==1.24.2 44 | openai==0.27.4 45 | packaging==23.0 46 | pandas==2.0.0 47 | parso==0.8.3 48 | Paste==3.5.2 49 | pathy==0.10.1 50 | pickleshare==0.7.5 51 | platformdirs==3.1.1 52 | preshed==3.0.8 53 | prompt-toolkit==3.0.38 54 | psutil==5.9.4 55 | pure-eval==0.2.2 56 | pydantic==1.10.7 57 | Pygments==2.14.0 58 | PyMySQL==1.0.3 59 | pyrsistent==0.19.3 60 | python-dateutil==2.8.2 61 | python-dotenv==1.0.0 62 | pytz==2023.3 63 | pywin32==305 64 | pyzmq==25.0.1 65 | smart-open==6.3.0 66 | soupsieve==2.4 67 | spacy==3.5.2 68 | spacy-legacy==3.0.12 69 | spacy-loggers==1.0.4 70 | srsly==2.4.6 71 | stack-data==0.6.2 72 | thinc==8.1.9 73 | tornado==6.2 74 | traitlets==5.9.0 75 | typer==0.7.0 76 | typing_extensions==4.5.0 77 | tzdata==2023.3 78 | waitress==2.1.2 79 | wasabi==1.1.1 80 | wcwidth==0.2.6 81 | Werkzeug==2.2.3 82 | wincertstore==0.2 83 | yarl==1.8.2 84 | zstandard==0.18.0 85 | -------------------------------------------------------------------------------- /exec/img/data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/exec/img/data.png -------------------------------------------------------------------------------- /exec/img/front-back-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/exec/img/front-back-server.png -------------------------------------------------------------------------------- /exec/modoostock_db_dump/modoostock-db-dump(20230519).zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/exec/modoostock_db_dump/modoostock-db-dump(20230519).zip -------------------------------------------------------------------------------- /exec/modoostock_db_dump/modoostock_hibernate_sequence.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.31, for Win64 (x86_64) 2 | -- 3 | -- Host: k8e206.p.ssafy.io Database: modoostock 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.33 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `hibernate_sequence` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `hibernate_sequence`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `hibernate_sequence` ( 26 | `next_val` bigint DEFAULT NULL 27 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 28 | /*!40101 SET character_set_client = @saved_cs_client */; 29 | 30 | -- 31 | -- Dumping data for table `hibernate_sequence` 32 | -- 33 | 34 | LOCK TABLES `hibernate_sequence` WRITE; 35 | /*!40000 ALTER TABLE `hibernate_sequence` DISABLE KEYS */; 36 | INSERT INTO `hibernate_sequence` VALUES (14); 37 | /*!40000 ALTER TABLE `hibernate_sequence` ENABLE KEYS */; 38 | UNLOCK TABLES; 39 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 40 | 41 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 42 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 43 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 44 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 45 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 46 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 47 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 48 | 49 | -- Dump completed on 2023-05-17 9:37:59 50 | -------------------------------------------------------------------------------- /exec/시연시나리오.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/exec/시연시나리오.docx -------------------------------------------------------------------------------- /front-server/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /front-server/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "bracketSpacing": true, 4 | "jsxBracketSameLine": true, 5 | "printWidth": 120, 6 | "singleQuote": true, 7 | "tabWidth": 2, 8 | "trailingComma": "none", 9 | "useTabs": false, 10 | "semi": true, 11 | "endOfLine": "auto" 12 | } 13 | -------------------------------------------------------------------------------- /front-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18.12.1 as build-stage 2 | WORKDIR /var/jenkins_home/workspace/modoostock-deploy/front-server 3 | COPY package*.json ./ 4 | 5 | # RUN npm install -g yarn 6 | RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 7 | RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list 8 | RUN apt-get update && apt-get install -y yarn 9 | 10 | RUN yarn install 11 | COPY . . 12 | RUN yarn build 13 | FROM nginx:stable-alpine as production-stage 14 | 15 | COPY --from=build-stage /var/jenkins_home/workspace/modoostock-deploy/front-server/build /usr/share/nginx/html 16 | COPY --from=build-stage /var/jenkins_home/workspace/modoostock-deploy/front-server/deploy-conf/nginx.conf /etc/nginx/conf.d/default.conf 17 | EXPOSE 80 18 | CMD ["nginx", "-g","daemon off;"] -------------------------------------------------------------------------------- /front-server/config-overrides.js: -------------------------------------------------------------------------------- 1 | // const { override } = require('customize-cra'); 2 | 3 | // // 웹뷰 앱에서 주소창을 숨기는 설정 4 | // const hideAddressBar = (config) => { 5 | // config.target = 'webview'; // 웹뷰 앱의 target 설정 6 | // config.mobile = true; // 모바일 기기에서 실행될 경우에만 적용 7 | // return config; 8 | // }; 9 | 10 | // module.exports = override(hideAddressBar); -------------------------------------------------------------------------------- /front-server/public/.well-known/assetlinks.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "relation": ["delegate_permission/common.handle_all_urls"], 4 | "target": { 5 | "namespace": "android_app", 6 | "package_name": "com.modoostock.twa", 7 | "sha256_cert_fingerprints": [ 8 | "4C:48:EB:69:F2:B1:4D:4C:54:5C:F6:65:AC:3D:45:86:23:4B:39:41:40:BA:6C:D3:3F:55:AF:B0:E6:0A:E6:74" 9 | ] 10 | } 11 | }, 12 | { 13 | "relation": ["delegate_permission/common.handle_all_urls"], 14 | "target": { 15 | "namespace": "android_app", 16 | "package_name": "com.modoostock.twa", 17 | "sha256_cert_fingerprints": [ 18 | "28:C4:4C:F5:CE:2F:8D:82:05:37:08:C4:AB:4F:E9:AD:B1:72:4C:B8:EB:CB:42:3A:6A:85:AA:CD:85:D2:07:4B" 19 | ] 20 | } 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /front-server/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/front-server/public/favicon.ico -------------------------------------------------------------------------------- /front-server/public/firebase-messaging-sw.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | self.addEventListener('message', (event) => { 4 | console.log(event.data) 5 | if (event.data && event.data.type === 'SKIP_WAITING') { 6 | self.skipWaiting(); 7 | } 8 | }); 9 | self.addEventListener('install', function (e) { 10 | self.skipWaiting(); 11 | }); 12 | 13 | self.addEventListener('activate', function (e) { 14 | }); 15 | 16 | self.addEventListener('push', function (e) { 17 | // console.log('1 push: ', e.data.json()); 18 | if (!e.data.json()) return; 19 | 20 | const resultData = e.data.json().notification; 21 | const notificationTitle = resultData.title; 22 | const notificationOptions = { 23 | body: resultData.body, 24 | icon: resultData.image, 25 | badge: "./images/icons/badge-72x72.png", 26 | vibrate: [200, 100, 200, 100, 200, 100, 200], 27 | tag: resultData.tag, 28 | ...resultData 29 | }; 30 | // console.log('2 push: ', { resultData, notificationTitle, notificationOptions }); 31 | // // 내 정보 이벤트실행시 API 32 | // const getUsers = () => { 33 | // console.log("유저정보가져오기") 34 | // } 35 | // getUsers(); 36 | 37 | 38 | self.registration.showNotification(notificationTitle, notificationOptions); 39 | }); 40 | 41 | self.addEventListener('notificationclick', function (event) { 42 | console.log('notification click'); 43 | const url = '/main'; 44 | event.notification.close(); 45 | event.waitUntil(clients.openWindow(url)); 46 | }); 47 | -------------------------------------------------------------------------------- /front-server/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 26 | 27 | 모두의 주식 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /front-server/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "모두의 주식", 3 | "name": "모두의 주식 for SSAFY", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "/images/icons/android-icon-36x36.png", 12 | "sizes": "36x36", 13 | "type": "image/png", 14 | "density": "0.75" 15 | }, 16 | { 17 | "src": "/images/icons/android-icon-48x48.png", 18 | "sizes": "48x48", 19 | "type": "image/png", 20 | "density": "1.0" 21 | }, 22 | { 23 | "src": "/images/icons/apple-icon-57x57.png", 24 | "sizes": "57x57", 25 | "type": "image/png" 26 | }, 27 | { 28 | "src": "/images/icons/apple-icon-60x60.png", 29 | "sizes": "60x60", 30 | "type": "image/png" 31 | }, 32 | { 33 | "src": "/images/icons/android-icon-72x72.png", 34 | "sizes": "72x72", 35 | "type": "image/png", 36 | "density": "1.5" 37 | }, 38 | { 39 | "src": "/images/icons/apple-icon-76x76.png", 40 | "sizes": "76x76", 41 | "type": "image/png", 42 | "density": "1.5" 43 | }, 44 | { 45 | "src": "/images/icons/apple-icon-114x114.png", 46 | "sizes": "114x114", 47 | "type": "image/png" 48 | }, 49 | { 50 | "src": "/images/icons/apple-icon-144x144.png", 51 | "sizes": "144x144", 52 | "type": "image/png" 53 | }, 54 | { 55 | "src": "/images/icons/android-icon-192x192.png", 56 | "sizes": "192x192", 57 | "type": "image/png", 58 | "density": "4.0", 59 | "purpose": "any" 60 | }, 61 | { 62 | "src": "/images/icons/icon-512x512.png", 63 | "sizes": "512x512", 64 | "type": "image/png", 65 | "purpose": "maskable" 66 | } 67 | ], 68 | "start_url": ".", 69 | "display": "fullscreen", 70 | "orientation": "landscape", 71 | "theme_color": "#000000", 72 | "background_color": "#ffffff" 73 | } 74 | -------------------------------------------------------------------------------- /front-server/public/open.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/front-server/public/open.wav -------------------------------------------------------------------------------- /front-server/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /front-server/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /front-server/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /front-server/src/Components/Admin/AdminMain.tsx: -------------------------------------------------------------------------------- 1 | import { useNavigate } from 'react-router-dom'; 2 | 3 | function AdminMain(): JSX.Element { 4 | const navigate = useNavigate(); 5 | const click = (e: React.MouseEvent) => { 6 | switch (e.currentTarget.ariaLabel) { 7 | case '유저': 8 | navigate('/admin/user'); 9 | break; 10 | case '주식': 11 | navigate('/admin/market'); 12 | break; 13 | case '에셋': 14 | navigate('/admin/asset'); 15 | break; 16 | case '거래': 17 | navigate('/admin/deal'); 18 | break; 19 | } 20 | }; 21 | return ( 22 | <> 23 |
24 |
25 |
29 | 유저 30 |
31 |
35 | 주식 시즌 36 |
37 |
41 | 에셋 42 |
43 |
47 | 거래내역 48 |
49 |
50 |
51 | 52 | ); 53 | } 54 | export default AdminMain; 55 | -------------------------------------------------------------------------------- /front-server/src/Components/Admin/AdminMarketModal.tsx: -------------------------------------------------------------------------------- 1 | import { useRef } from 'react'; 2 | 3 | interface SelectMarketDataType { 4 | companyName: string; 5 | companyKind: string; 6 | average: number; 7 | } 8 | 9 | interface AdminMarketModalProps { 10 | selectMarketData: SelectMarketDataType[]; 11 | setIsClick: React.Dispatch>; 12 | } 13 | 14 | function AdminMarketModal({ selectMarketData, setIsClick }: AdminMarketModalProps): JSX.Element { 15 | const ref = useRef(null); 16 | const tbodyData = selectMarketData.map((marketData, idx) => { 17 | return ( 18 | 19 | {marketData.companyName} 20 | {marketData.companyKind} 21 | 22 | {marketData.average.toLocaleString()} 원 23 | 24 | 25 | ); 26 | }); 27 | return ( 28 | <> 29 |
{ 33 | if (e.target === ref.current) { 34 | setIsClick(false); 35 | } 36 | }}> 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {tbodyData} 47 |
companyNamecompanyKindaverage
48 |
49 |
50 | 51 | ); 52 | } 53 | export default AdminMarketModal; 54 | -------------------------------------------------------------------------------- /front-server/src/Components/Admin/AdminPage.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { Outlet, useNavigate } from 'react-router-dom'; 3 | import Loading from '../Common/Loading'; 4 | import { useGetAdminUserCheckQuery } from 'Store/api'; 5 | 6 | function AdminPage(): JSX.Element { 7 | const navigate = useNavigate(); 8 | const { data, isLoading } = useGetAdminUserCheckQuery(''); 9 | 10 | if (data?.data !== true) { 11 | navigate('/main'); 12 | } 13 | 14 | return ( 15 | <> 16 | {isLoading ? ( 17 | 18 | ) : ( 19 | <> 20 |
21 |
{ 24 | navigate(-1); 25 | }}> 26 | ⬅ 27 |
28 |
{ 31 | navigate(+1); 32 | }}> 33 | ➡ 34 |
35 |
36 | 37 | 38 | )} 39 | 40 | ); 41 | } 42 | export default AdminPage; 43 | -------------------------------------------------------------------------------- /front-server/src/Components/Chatting/Chat.tsx: -------------------------------------------------------------------------------- 1 | import Chatting from './Chatting'; 2 | import ChemiChatting from './ChemiChatting'; 3 | import ElectricChatting from './ElectricChatting'; 4 | import ITChatting from './ITChatting'; 5 | import LifeChatting from './LifeChatting'; 6 | import SystemChatting from './SystemChatting'; 7 | 8 | type ChatProps = { 9 | data : string 10 | } 11 | 12 | function Chat({data}: ChatProps): JSX.Element { 13 | switch (data) { 14 | case "투자": 15 | return ( 16 | 17 | ) 18 | case "전체": 19 | return ( 20 | 21 | ) 22 | case "전자": 23 | return ( 24 | 25 | ) 26 | case "화학": 27 | return ( 28 | 29 | ) 30 | case "생명": 31 | return ( 32 | 33 | ) 34 | case "IT": 35 | return ( 36 | 37 | ) 38 | default: 39 | return ( 40 | <> 41 | ) 42 | } 43 | } 44 | export default Chat; 45 | -------------------------------------------------------------------------------- /front-server/src/Components/Common/AssetLoading.tsx: -------------------------------------------------------------------------------- 1 | import Lottie from 'lottie-react'; 2 | import LoadingLottie from './Lottie/133381-house-pop-up.json'; 3 | function AssetLoading(): JSX.Element { 4 | return ( 5 | <> 6 |
7 |
8 | 9 | {/*
집을 불러오는 중입니다.
*/} 10 |
11 |
12 | 13 | ); 14 | } 15 | 16 | export default AssetLoading; 17 | -------------------------------------------------------------------------------- /front-server/src/Components/Common/Error.tsx: -------------------------------------------------------------------------------- 1 | import Lottie from "lottie-react"; 2 | import ErrorLottie from "./Lottie/94992-error-404.json"; 3 | import { useNavigate } from "react-router-dom"; 4 | 5 | 6 | function Error():JSX.Element { 7 | const navigate = useNavigate(); 8 | 9 | return( 10 | <> 11 |
12 |
13 | 14 |
잘못된 접근입니다.
15 |
navigate('/main')}>메인화면으로 이동
16 |
17 |
18 | 19 | ) 20 | } 21 | 22 | export default Error; -------------------------------------------------------------------------------- /front-server/src/Components/Common/Loading.tsx: -------------------------------------------------------------------------------- 1 | import Lottie from "lottie-react"; 2 | import LoadingLottie from "./Lottie/140765-money.json"; 3 | import { useNavigate } from "react-router-dom"; 4 | 5 | 6 | function Loading():JSX.Element { 7 | const navigate = useNavigate(); 8 | 9 | return( 10 | <> 11 |
12 |
13 | 14 |
로딩중입니다.
15 |
navigate('/main')}>메인화면으로 이동
16 |
17 |
18 | 19 | ) 20 | } 21 | 22 | export default Loading; -------------------------------------------------------------------------------- /front-server/src/Components/Common/RotateDevice.tsx: -------------------------------------------------------------------------------- 1 | import Lottie from "lottie-react"; 2 | import Device from "./Lottie/rotateDevice.json"; 3 | 4 | function RotateDevice():JSX.Element { 5 | 6 | return( 7 | <> 8 |
9 |
10 | 11 |
모두의주식은 가로모드로 즐겨주세요
12 |
13 |
14 | 15 | ) 16 | } 17 | 18 | export default RotateDevice; -------------------------------------------------------------------------------- /front-server/src/Components/Common/SetPushToken.tsx: -------------------------------------------------------------------------------- 1 | 2 | // 파이어베이스 3 | import { dbService } from '../../firebase'; 4 | import { setDoc, doc, serverTimestamp } from 'firebase/firestore'; 5 | 6 | 7 | const SetPushToken = async (nickname : string, token: string) => { 8 | const roomName = 'PushToken'; 9 | 10 | // 메시지 데이터에 추가 11 | await setDoc(doc(dbService, roomName, `${nickname}`), { 12 | nickname, 13 | token, 14 | createdAt: serverTimestamp() 15 | }); 16 | }; 17 | 18 | export default SetPushToken; 19 | -------------------------------------------------------------------------------- /front-server/src/Components/Common/Toast.tsx: -------------------------------------------------------------------------------- 1 | import { ToastContainer } from "react-toastify"; 2 | import styled from 'styled-components' 3 | 4 | export const Toast = styled(ToastContainer).attrs({ 5 | autoClose:1000, 6 | pauseOnHover: false, 7 | hideProgressBar: true, 8 | pauseOnFocusLoss: false, 9 | 10 | })` 11 | 12 | .Toastify__toast { 13 | font-size: 1rem; 14 | border-radius: 0.5rem; 15 | padding: 1rem 1.5rem; 16 | color: #767676; 17 | font-weight:bold; 18 | background: rgba(255, 255, 255, 0.8); 19 | 20 | } 21 | 22 | .Toastify__toast-icon { 23 | width: 1.5rem; 24 | height: 1.5rem; 25 | } 26 | 27 | .Toastify__toast--info { 28 | background: rgba(255, 255, 255, 0.8); 29 | } 30 | 31 | .Toastify__toast--success { 32 | background: rgba(255, 255, 255, 0.8); 33 | } 34 | 35 | .Toastify__toast--error { 36 | background: rgba(255, 255, 255, 0.8); 37 | } 38 | ` -------------------------------------------------------------------------------- /front-server/src/Components/Exchange/Chart.tsx: -------------------------------------------------------------------------------- 1 | import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, ComposedChart } from 'recharts'; 2 | 3 | function Chart({ data }: any) { 4 | const formatYAxis = (tickItem: any) => tickItem.toLocaleString() + '원'; 5 | const formatTooltip = (tickItem: any) => tickItem.toLocaleString(); 6 | 7 | return ( 8 | 9 | 19 | 20 | 21 | 26 | (name === '종가' ? value.toLocaleString() + '원' : value)} 29 | /> 30 | 31 | 32 | 33 | 34 | ); 35 | } 36 | export default Chart; 37 | -------------------------------------------------------------------------------- /front-server/src/Components/Exchange/CountdownTimeMinute.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | function CountdownTimeMinute(): JSX.Element { 4 | const date = new Date(); 5 | const [time, setTime] = useState<{ minutes: number; seconds: number }>({ 6 | minutes: 4 - ((date.getMinutes() % 4) % 4) - 1, 7 | seconds: 60 - date.getSeconds() - 1 8 | }); 9 | const day = date.getDay(); 10 | 11 | useEffect(() => { 12 | const date = new Date(); 13 | const hours = date.getHours(); 14 | const minutes = date.getMinutes(); 15 | if (day === 0) { 16 | setTime({ minutes: 0, seconds: 0 }); 17 | } else { 18 | if (hours < 10 || hours >= 22) { 19 | setTime({ minutes: 0, seconds: 0 }); 20 | } else { 21 | setTime({ 22 | minutes: 4 - ((minutes % 4) % 4) - 1, 23 | seconds: 60 - date.getSeconds() - 1 24 | }); 25 | const intervalId = setInterval(() => { 26 | setTime((preTime) => { 27 | const { minutes, seconds } = preTime; 28 | if (minutes === 0 && seconds === 0) { 29 | return { minutes: 3, seconds: 59 }; 30 | } else { 31 | if (minutes !== 0 && seconds === 0) { 32 | return { minutes: minutes - 1, seconds: 59 }; 33 | } else { 34 | return { minutes: minutes, seconds: seconds - 1 }; 35 | } 36 | } 37 | }); 38 | }, 1000); 39 | return () => clearInterval(intervalId); 40 | } 41 | } 42 | }, []); 43 | return ( 44 | <> 45 | {time.minutes.toString().padStart(2, '0')} : {time.seconds.toString().padStart(2, '0')} 46 | 47 | ); 48 | } 49 | 50 | export default CountdownTimeMinute; 51 | -------------------------------------------------------------------------------- /front-server/src/Components/Exchange/Exchange.module.css: -------------------------------------------------------------------------------- 1 | .scroll::-webkit-scrollbar { 2 | display: none; 3 | } 4 | 5 | .scroll { 6 | -ms-overflow-style: none; /* 인터넷 익스플로러 */ 7 | scrollbar-width: none; /* 파이어폭스 */ 8 | } 9 | -------------------------------------------------------------------------------- /front-server/src/Components/Main/Modal.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, useEffect, useRef } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | type ModalProps = { 5 | isOpen: boolean; 6 | onClose: () => void; 7 | children: React.ReactNode; 8 | padding?: string; 9 | canOpenModal?: boolean; 10 | elementId?: string; 11 | styleType?: number; 12 | }; 13 | 14 | const Modal: FC = ({ 15 | isOpen, 16 | onClose, 17 | children, 18 | padding = '', 19 | canOpenModal = true, 20 | elementId = 'modal-root', 21 | styleType = 1 22 | }) => { 23 | const modalRef = useRef(null); 24 | const el = document.getElementById(elementId); 25 | 26 | useEffect(() => { 27 | const handleClickOutside = (event: MouseEvent) => { 28 | if (canOpenModal && modalRef.current && !modalRef.current.contains(event.target as Node)) { 29 | onClose(); 30 | } 31 | }; 32 | 33 | if (isOpen) { 34 | document.addEventListener('mousedown', handleClickOutside); 35 | } 36 | 37 | return () => { 38 | document.removeEventListener('mousedown', handleClickOutside); 39 | }; 40 | }, [isOpen, onClose, canOpenModal]); 41 | 42 | if (!isOpen) return null; 43 | 44 | return ReactDOM.createPortal( 45 |
46 | {styleType === 1 && ( 47 |
53 | {children} 54 |
55 | )} 56 | {styleType === 2 && ( 57 |
58 | {children} 59 |
60 | )} 61 |
, 62 | el as HTMLElement 63 | ); 64 | }; 65 | 66 | export default Modal; 67 | -------------------------------------------------------------------------------- /front-server/src/Components/Main/MyHomeAsset.tsx: -------------------------------------------------------------------------------- 1 | import { useGLTF } from '@react-three/drei'; 2 | import { useRef } from 'react'; 3 | function MyHomeAsset({ len, pos, rot }: any): JSX.Element { 4 | const li = Math.floor(Math.random() * new Array(20).length); 5 | const { nodes, materials }: any = useGLTF(process.env.REACT_APP_S3_URL + `/assets/mainHouse/house${li}.gltf`); 6 | const ref = useRef(null); 7 | 8 | let cnt = -1; 9 | let geo: any = []; 10 | for (const key in nodes) { 11 | cnt += 1; 12 | if (!(cnt === 0 || cnt === 1)) { 13 | geo = [...geo, nodes[key].geometry]; 14 | } 15 | } 16 | 17 | let meshPosition: any = []; 18 | 19 | Object.values(nodes).map((item: any, idx) => { 20 | if (!(idx === 0 || idx === 1)) { 21 | let li: any = []; 22 | Object.values(item.position).map((po: any) => { 23 | li = [...li, Math.round(po * 100) / 100]; 24 | }); 25 | meshPosition = [...meshPosition, li]; 26 | } 27 | }); 28 | 29 | // 데이터 30 | const meshData = meshPosition.map((data: any, idx: number) => { 31 | return ( 32 | 38 | ); 39 | }); 40 | 41 | return ( 42 | 43 | 44 | {meshData} 45 | 46 | 47 | ); 48 | } 49 | export default MyHomeAsset; 50 | -------------------------------------------------------------------------------- /front-server/src/Components/Main/MyHomeAsset2.tsx: -------------------------------------------------------------------------------- 1 | import { useGLTF } from '@react-three/drei'; 2 | import { useRef } from 'react'; 3 | function MyHomeAsset2({ len, pos, rot }: any): JSX.Element { 4 | const li = Math.floor(Math.random() * new Array(20).length); 5 | const { nodes, materials }: any = useGLTF(process.env.REACT_APP_S3_URL + `/assets/mainHouse/house${li}.gltf`); 6 | const ref = useRef(null); 7 | 8 | let cnt = -1; 9 | let geo: any = []; 10 | for (const key in nodes) { 11 | cnt += 1; 12 | if (!(cnt === 0 || cnt === 1)) { 13 | geo = [...geo, nodes[key].geometry]; 14 | } 15 | } 16 | 17 | let meshPosition: any = []; 18 | 19 | Object.values(nodes).map((item: any, idx) => { 20 | if (!(idx === 0 || idx === 1)) { 21 | let li: any = []; 22 | Object.values(item.position).map((po: any) => { 23 | li = [...li, Math.round(po * 100) / 100]; 24 | }); 25 | meshPosition = [...meshPosition, li]; 26 | } 27 | }); 28 | 29 | // 데이터 30 | const meshData = meshPosition.map((data: any, idx: number) => { 31 | return ( 32 | 38 | ); 39 | }); 40 | 41 | return ( 42 | 43 | 44 | {meshData} 45 | 46 | 47 | ); 48 | } 49 | export default MyHomeAsset2; 50 | -------------------------------------------------------------------------------- /front-server/src/Components/Main/ShowMyRoomAssets.tsx: -------------------------------------------------------------------------------- 1 | import { useGLTF } from '@react-three/drei'; 2 | import { useFrame, useThree } from '@react-three/fiber'; 3 | import { useRef, useState } from 'react'; 4 | 5 | function ShowMyRoomAssets({ len, pos, rot }: any): JSX.Element { 6 | const { nodes, materials }: any = useGLTF(process.env.REACT_APP_S3_URL + '/assets/model.gltf'); 7 | const [scale, setScale] = useState(len); // Bathroom 컴포넌트의 scale 값을 useState로 관리 8 | 9 | const ref = useRef(null); 10 | 11 | let cnt = -1; 12 | let geo: any = []; 13 | for (const key in nodes) { 14 | cnt += 1; 15 | if (!(cnt === 0)) { 16 | geo = [...geo, nodes[key].geometry]; 17 | } 18 | } 19 | let meshPosition: any = []; 20 | 21 | Object.values(nodes).map((item: any, idx) => { 22 | if (!(idx === 0)) { 23 | let li: any = []; 24 | Object.values(item.position).map((po: any) => { 25 | li = [...li, Math.round(po * 100) / 100]; 26 | }); 27 | meshPosition = [...meshPosition, li]; 28 | } 29 | }); 30 | 31 | // 데이터 32 | const meshData = meshPosition.map((data: any, idx: number) => { 33 | return ( 34 | 40 | ); 41 | }); 42 | 43 | // size를 받아옴 44 | const { size } = useThree(); 45 | useFrame(() => { 46 | // 화면의 비율이 변경될 때마다 scale 값을 변경함 47 | setScale(Math.max(size.width, size.height) * 0.0000122); 48 | }); 49 | 50 | return ( 51 | { 54 | e.stopPropagation(); 55 | // console.log('집'); 56 | }}> 57 | 58 | {meshData} 59 | 60 | 61 | ); 62 | } 63 | export default ShowMyRoomAssets; 64 | -------------------------------------------------------------------------------- /front-server/src/Components/Main/SundayModal.tsx: -------------------------------------------------------------------------------- 1 | import { useRef } from 'react'; 2 | import CashUFOLottie from '../Common/Lottie/96583-ufo-stealing-money.json'; 3 | import Lottie from 'lottie-react'; 4 | import { AnimatePresence, motion } from 'framer-motion'; 5 | import { cancelPlay } from 'Store/store'; 6 | import { useAppDispatch } from 'Store/hooks'; 7 | 8 | interface Type { 9 | setSundayModal: React.Dispatch>; 10 | } 11 | function SundayModal({ setSundayModal }: Type): JSX.Element { 12 | const dispatch = useAppDispatch(); 13 | const ref = useRef(null); 14 | return ( 15 | <> 16 | { 27 | if (e.target === ref.current) { 28 | setSundayModal(false); 29 | } 30 | }}> 31 |
32 | 33 |
34 | 이용 가능 시간 35 | 월요일 ~ 토요일 36 | AM 10:00 ~ PM 10:00 37 |
38 |
{ 41 | setSundayModal(false); 42 | dispatch(cancelPlay()); 43 | }}> 44 | 닫기 45 |
46 |
47 |
48 | 49 | ); 50 | } 51 | export default SundayModal; 52 | -------------------------------------------------------------------------------- /front-server/src/Components/MiniGame/Lottery.module.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'BMEULJIRO'; 3 | src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_twelve@1.0/BMEULJIRO.woff') format('woff'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | 8 | @font-face { 9 | font-family: 'SBAggroB'; 10 | src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2108@1.1/SBAggroB.woff') format('woff'); 11 | font-weight: normal; 12 | font-style: normal; 13 | } 14 | 15 | .font { 16 | font-family: 'BMEULJIRO'; 17 | -webkit-user-select: none; 18 | -moz-user-select: none; 19 | -ms-user-select: none; 20 | user-select: none; 21 | } 22 | 23 | .font2 { 24 | font-family: 'SBAggroB'; 25 | -webkit-user-select: none; 26 | -moz-user-select: none; 27 | -ms-user-select: none; 28 | user-select: none; 29 | } -------------------------------------------------------------------------------- /front-server/src/Components/Rank/Rank.module.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'MaplestoryOTFBold'; 3 | src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_20-04@2.1/MaplestoryOTFBold.woff') format('woff'); 4 | font-weight: normal; 5 | font-style: normal; 6 | } 7 | 8 | .font { 9 | font-family: 'MaplestoryOTFBold'; 10 | -webkit-user-select: none; 11 | -moz-user-select: none; 12 | -ms-user-select: none; 13 | user-select: none; 14 | } -------------------------------------------------------------------------------- /front-server/src/Store/FirebaseApi.ts: -------------------------------------------------------------------------------- 1 | 2 | import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/dist/query/react'; 3 | 4 | // 타입 5 | interface SendPushStateInterFace { 6 | account: string; 7 | nickname: string; 8 | password: string; 9 | } 10 | 11 | 12 | export const FirebaseApi = createApi({ 13 | reducerPath: 'FirebaseApi', 14 | tagTypes: ['FirebaseApi'], 15 | baseQuery: fetchBaseQuery({ 16 | baseUrl: process.env.REACT_APP_FCM_URL, 17 | prepareHeaders: async (headers) => { 18 | // By default, if we have a token in the store, let's use that for authenticated requests 19 | headers.set('Authorization', `bearer ${process.env.REACT_APP_FCM_SERVER_KEY}`); 20 | headers.set('Content-Type', 'application/json',); 21 | return headers; 22 | } 23 | }), 24 | 25 | endpoints: (builder) => ({ 26 | // 1. 웹 푸시용 27 | postSendPush: builder.mutation({ 28 | query: (data) => { 29 | return { 30 | url: ``, 31 | method: 'POST', 32 | body: data 33 | }; 34 | }, 35 | invalidatesTags: (result, error, arg) => [{ type: 'FirebaseApi' }] 36 | }) 37 | }) 38 | }); 39 | 40 | export const { 41 | usePostSendPushMutation, 42 | 43 | } = FirebaseApi; 44 | -------------------------------------------------------------------------------- /front-server/src/Store/hooks.ts: -------------------------------------------------------------------------------- 1 | // hooks.ts 파일을 따로 만는 이유 2 | // Redux toolkit를 TypeScript와 함께 사용하려면 useSelector와 useDispatch를 TypeScript 버전으로 변경해줘야 하는데 3 | // 이런 타입화 과정을 모든 컴포넌트에 적용하는 것보다는 hooks.ts라는 파일에서 만들어 pre-typed된 버전을 만들어주는 것이 편하다. 4 | 5 | import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' 6 | import type { RootState, AppDispatch } from './store' 7 | 8 | export const useAppDispatch: () => AppDispatch = useDispatch 9 | export const useAppSelector: TypedUseSelectorHook = useSelector -------------------------------------------------------------------------------- /front-server/src/firebase.tsx: -------------------------------------------------------------------------------- 1 | // Import the functions you need from the SDKs you need 2 | import { initializeApp } from 'firebase/app'; 3 | import { getFirestore } from 'firebase/firestore'; 4 | import { getMessaging } from 'firebase/messaging'; 5 | // import { getStorage } from "firebase/storage"; 6 | // TODO: Add SDKs for Firebase products that you want to use 7 | // https://firebase.google.com/docs/web/setup#available-libraries 8 | 9 | // Your web app's Firebase configuration 10 | const firebaseConfig = { 11 | apiKey: process.env.REACT_APP_API_KEY, 12 | authDomain: process.env.REACT_APP_AUTH_DOMAIN, 13 | projectId: process.env.REACT_APP_PROJECT_ID, 14 | storageBucket: process.env.REACT_APP_STORAGE_BUCKET, 15 | messagingSenderId: process.env.REACT_APP_MESSAGIN_ID, 16 | appId: process.env.REACT_APP_APP_ID 17 | }; 18 | 19 | // Initialize Firebase 20 | const app = initializeApp(firebaseConfig); 21 | const dbService = getFirestore(app); 22 | const messaging = getMessaging(app); 23 | // const storageService = getStorage(app); 24 | 25 | 26 | async function requestPermission() { 27 | const permission = await Notification.requestPermission(); 28 | if (permission === 'denied') { 29 | console.log('알림 권한 허용 안됨'); 30 | return; 31 | } 32 | 33 | // const token = await getToken(messaging, { 34 | // vapidKey: process.env.REACT_APP_FCM_VAPID 35 | // }); 36 | // if (token) { 37 | // console.log('token: ', token); 38 | // } else { 39 | // console.log('Can not get Token'); 40 | // } 41 | 42 | } 43 | requestPermission(); 44 | 45 | export { app, dbService, messaging }; 46 | -------------------------------------------------------------------------------- /front-server/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* @media screen and (orientation: portrait) { 6 | body { 7 | transform: rotate(90deg); 8 | transform-origin: top left; 9 | width: 100vh; 10 | height: 100vw; 11 | overflow-x: hidden; 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | content: '뒤로 돌아가'; 16 | } 17 | } */ 18 | * { 19 | touch-action: manipulation; 20 | } 21 | 22 | /* 후보 1 */ 23 | @font-face { 24 | font-family: 'IBMPlexSansKR-Regular'; 25 | src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_20-07@1.0/IBMPlexSansKR-Regular.woff') format('woff'); 26 | font-weight: normal; 27 | font-style: normal; 28 | } 29 | 30 | * { 31 | font-family: 'IBMPlexSansKR-Regular'; 32 | -webkit-user-select: none; 33 | -moz-user-select: none; 34 | -ms-user-select: none; 35 | user-select: none; 36 | } 37 | 38 | @media (min-width: 1024px) { 39 | div::-webkit-scrollbar { 40 | width: 0.5rem; /* 스크롤바의 너비 */ 41 | } 42 | div::-webkit-scrollbar-thumb { 43 | height: 20%; 44 | background: #ffa3c5; /* 스크롤바의 색상 */ 45 | 46 | border-radius: 10px; 47 | } 48 | div::-webkit-scrollbar-track { 49 | background: #ffffff; 50 | } 51 | } 52 | 53 | * { 54 | -webkit-user-drag: none; 55 | } 56 | -------------------------------------------------------------------------------- /front-server/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorkerRegistration from './serviceWorkerRegistration'; 6 | import reportWebVitals from './reportWebVitals'; 7 | import { BrowserRouter } from 'react-router-dom'; 8 | // redux 9 | import { Provider } from 'react-redux'; 10 | import { store } from 'Store/store'; 11 | 12 | const root = ReactDOM.createRoot( 13 | document.getElementById('root') as HTMLElement 14 | ); 15 | root.render( 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | // If you want your app to work offline and load faster, you can change 24 | // unregister() to register() below. Note this comes with some pitfalls. 25 | // Learn more about service workers: https://cra.link/PWA 26 | // serviceWorkerRegistration.unregister(); 27 | serviceWorkerRegistration.register(); 28 | 29 | // If you want to start measuring performance in your app, pass a function 30 | // to log results (for example: reportWebVitals(console.log)) 31 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 32 | reportWebVitals(); 33 | -------------------------------------------------------------------------------- /front-server/src/intro/IntroBG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/front-server/src/intro/IntroBG.png -------------------------------------------------------------------------------- /front-server/src/intro/money.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/front-server/src/intro/money.png -------------------------------------------------------------------------------- /front-server/src/intro/newspaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Isanghada/ModooStock/134ef449e156ee085712251657035dc7cc39fbc8/front-server/src/intro/newspaper.png -------------------------------------------------------------------------------- /front-server/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /front-server/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /front-server/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /front-server/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | 3 | module.exports = { 4 | content: ['./src/**/*.{js,jsx,ts,tsx}'], 5 | theme: { 6 | extend: { 7 | fontFamily: { 8 | // sans: ["Nanum Gothic"], 9 | nanum: ["Nanum Gothic"], 10 | }, 11 | animation: { 12 | moving: 'moving 3s linear infinite', 13 | open: 'open 2s linear infinite', 14 | }, 15 | 16 | keyframes: { 17 | moving: { 18 | '0%, 100%': { transform: 'translateY(0rem)' }, 19 | '50%': { transform: 'translateY(0.22rem)' } 20 | }, 21 | ring: { 22 | '0%': { 23 | transform: 'rotate(0deg)' 24 | }, 25 | '10%': { 26 | transform: 'rotate(15deg)' 27 | }, 28 | '20%': { 29 | transform: 'rotate(-15deg)' 30 | }, 31 | '30%': { 32 | transform: 'rotate(10deg)' 33 | }, 34 | '40%': { 35 | transform: 'rotate(-10deg)' 36 | }, 37 | '50%': { 38 | transform: 'rotate(5deg)' 39 | }, 40 | '60%': { 41 | transform: 'rotate(-5deg)' 42 | }, 43 | '70%': { 44 | transform: 'rotate(0deg)' 45 | }, 46 | '100%': { 47 | transform: 'rotate(0deg)' 48 | } 49 | }, 50 | open: { 51 | '0%': { 52 | transform: 'scale(1)', 53 | }, 54 | '50%': { 55 | transform: 'scale(1.1)', 56 | }, 57 | '100%': { 58 | transform: 'scale(1)', 59 | } 60 | } 61 | } 62 | } 63 | }, 64 | plugins: [] 65 | }; 66 | -------------------------------------------------------------------------------- /front-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src", 4 | "target": "es5", 5 | "lib": [ 6 | "dom", 7 | "dom.iterable", 8 | "esnext" 9 | ], 10 | "allowJs": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "allowSyntheticDefaultImports": true, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "noEmit": true, 22 | "jsx": "react-jsx", 23 | }, 24 | "include": [ 25 | "src" ] 26 | } 27 | --------------------------------------------------------------------------------