├── settings.gradle ├── .travis.yml ├── src ├── main │ ├── resources │ │ ├── favicon.ico │ │ ├── static │ │ │ ├── img │ │ │ │ ├── logo.jpg │ │ │ │ ├── error_404.png │ │ │ │ └── error_500.png │ │ │ ├── naver0110416977c450401d78ac7e3daa0f31.html │ │ │ ├── webfonts │ │ │ │ ├── NanumBarunGothicWeb.eot │ │ │ │ ├── NanumBarunGothicWeb.ttf │ │ │ │ ├── NanumBarunGothicWeb.woff │ │ │ │ ├── NanumBarunGothicWebBold.eot │ │ │ │ ├── NanumBarunGothicWebBold.ttf │ │ │ │ ├── NanumBarunGothicWebBold.woff │ │ │ │ ├── NanumBarunGothicWebLight.eot │ │ │ │ ├── NanumBarunGothicWebLight.ttf │ │ │ │ └── NanumBarunGothicWebLight.woff │ │ │ ├── lib │ │ │ │ ├── fontawesome-free-5.0.9 │ │ │ │ │ ├── webfonts │ │ │ │ │ │ ├── fa-solid-900.eot │ │ │ │ │ │ ├── fa-solid-900.ttf │ │ │ │ │ │ ├── fa-brands-400.eot │ │ │ │ │ │ ├── fa-brands-400.ttf │ │ │ │ │ │ ├── fa-brands-400.woff │ │ │ │ │ │ ├── fa-brands-400.woff2 │ │ │ │ │ │ ├── fa-regular-400.eot │ │ │ │ │ │ ├── fa-regular-400.ttf │ │ │ │ │ │ ├── fa-regular-400.woff │ │ │ │ │ │ ├── fa-solid-900.woff │ │ │ │ │ │ ├── fa-solid-900.woff2 │ │ │ │ │ │ └── fa-regular-400.woff2 │ │ │ │ │ └── css │ │ │ │ │ │ ├── fa-brands.min.css │ │ │ │ │ │ ├── fa-solid.min.css │ │ │ │ │ │ ├── fa-regular.min.css │ │ │ │ │ │ ├── fa-brands.css │ │ │ │ │ │ ├── fa-solid.css │ │ │ │ │ │ └── fa-regular.css │ │ │ │ ├── parsley-2.8.1 │ │ │ │ │ └── i18n │ │ │ │ │ │ ├── ko.js │ │ │ │ │ │ └── en.js │ │ │ │ └── countUp-1.9.3 │ │ │ │ │ └── countUp.min.js │ │ │ ├── js │ │ │ │ ├── layout.min.js │ │ │ │ ├── layout.js │ │ │ │ ├── admin │ │ │ │ │ ├── Horyu.View.Login.min.js │ │ │ │ │ ├── Horyu.View.EventHistoryView.min.js │ │ │ │ │ ├── Horyu.View.Login.js │ │ │ │ │ ├── Horyu.View.EventHistoryView.js │ │ │ │ │ ├── Horyu.View.Login.min.js.map │ │ │ │ │ ├── Horyu.View.EventHistoryView.min.js.map │ │ │ │ │ ├── Horyu.View.EventHistory.min.js │ │ │ │ │ ├── Horyu.View.Duplicated.min.js │ │ │ │ │ ├── Horyu.View.EventHistory.min.js.map │ │ │ │ │ ├── Horyu.View.EventHistory.js │ │ │ │ │ ├── Horyu.View.EventSetting.min.js │ │ │ │ │ ├── Horyu.View.CompanySetting.min.js │ │ │ │ │ ├── Horyu.View.ApplicantList.min.js │ │ │ │ │ ├── Horyu.View.PrizeSetting.min.js │ │ │ │ │ ├── Horyu.View.Lottery.min.js │ │ │ │ │ └── Horyu.View.EventSetting.min.js.map │ │ │ │ ├── layout.min.js.map │ │ │ │ ├── Horyu.View.Check.min.js │ │ │ │ ├── Horyu.View.Check.js │ │ │ │ ├── Horyu.View.Check.min.js.map │ │ │ │ ├── component │ │ │ │ │ └── Horyu.View.CompanyGiftTable.min.js │ │ │ │ └── Horyu.View.Apply.min.js │ │ │ ├── css │ │ │ │ ├── apply.min.css │ │ │ │ ├── admin.min.css │ │ │ │ ├── apply.css │ │ │ │ ├── style.min.css │ │ │ │ ├── admin.css │ │ │ │ ├── font.min.css │ │ │ │ ├── style.css │ │ │ │ └── font.css │ │ │ └── manifest.json │ │ ├── templates │ │ │ ├── view │ │ │ │ ├── apply │ │ │ │ │ ├── invalidForm.html │ │ │ │ │ ├── alreadyEnd.html │ │ │ │ │ ├── success.html │ │ │ │ │ ├── reduplication.html │ │ │ │ │ ├── failReCaptcha.html │ │ │ │ │ └── wrongWay.html │ │ │ │ ├── check │ │ │ │ │ ├── notOpenEvent.html │ │ │ │ │ ├── notExistApply.html │ │ │ │ │ ├── existApply.html │ │ │ │ │ └── check.html │ │ │ │ ├── failReCaptcha.html │ │ │ │ ├── component │ │ │ │ │ └── companyGiftTable.html │ │ │ │ ├── error │ │ │ │ │ ├── 404.html │ │ │ │ │ └── 500.html │ │ │ │ └── admin │ │ │ │ │ ├── eventHistoryView.html │ │ │ │ │ ├── eventHistory.html │ │ │ │ │ ├── login.html │ │ │ │ │ ├── applicantList.html │ │ │ │ │ └── duplicated.html │ │ │ └── navbar.html │ │ ├── banner.txt │ │ └── application.default.yml │ └── java │ │ └── com │ │ └── horyu1234 │ │ └── eventangel │ │ ├── constant │ │ ├── EventStatus.java │ │ ├── EventDetailStatus.java │ │ └── View.java │ │ ├── config │ │ ├── HttpSessionConfig.java │ │ ├── MinifyConfig.java │ │ ├── WebMVCConfig.java │ │ └── HttpSecureConfig.java │ │ ├── EventAngelApplication.java │ │ ├── form │ │ ├── CheckForm.java │ │ ├── LoginForm.java │ │ ├── CompanySaveForm.java │ │ ├── ApplyForm.java │ │ ├── PrizeSaveForm.java │ │ └── EventSettingForm.java │ │ ├── factory │ │ ├── SessionAttributeNameFactory.java │ │ ├── DateFactory.java │ │ └── ModelAttributeNameFactory.java │ │ ├── controller │ │ ├── HomeController.java │ │ ├── PrivacyController.java │ │ ├── admin │ │ │ ├── DuplicatedController.java │ │ │ ├── rest │ │ │ │ ├── LotteryRestController.java │ │ │ │ ├── PrizeSettingRestController.java │ │ │ │ ├── DuplicatedRestController.java │ │ │ │ ├── CompanySettingRestController.java │ │ │ │ ├── EventSettingRestController.java │ │ │ │ └── ApplicantListRestController.java │ │ │ ├── ApplicantListController.java │ │ │ ├── PrizeController.java │ │ │ ├── EventHistoryController.java │ │ │ ├── CompanySettingController.java │ │ │ ├── EventSettingController.java │ │ │ └── LotteryController.java │ │ ├── CustomErrorController.java │ │ └── rest │ │ │ └── CompanyLogoImageRestController.java │ │ ├── domain │ │ ├── DuplicatedApplicant.java │ │ ├── Account.java │ │ ├── EventWinner.java │ │ ├── Prize.java │ │ ├── Company.java │ │ ├── EventWinnerDetail.java │ │ ├── Event.java │ │ ├── CompanyAndPrize.java │ │ └── Applicant.java │ │ ├── CharResponseWrapper.java │ │ ├── database │ │ ├── mapper │ │ │ ├── CompanyMapper.java │ │ │ ├── EventWinnerMapper.java │ │ │ ├── EventMapper.java │ │ │ └── ApplicantMapper.java │ │ └── dao │ │ │ ├── AccountDAO.java │ │ │ ├── EventWinnerDAO.java │ │ │ ├── EventDAO.java │ │ │ ├── PrizeDAO.java │ │ │ └── CompanyDAO.java │ │ ├── interceptor │ │ └── AuthenticationInterceptor.java │ │ ├── service │ │ ├── AccountService.java │ │ ├── LotteryService.java │ │ ├── ReCaptchaService.java │ │ ├── ApplicantService.java │ │ ├── EventWinnerService.java │ │ ├── EventService.java │ │ ├── PrizeService.java │ │ └── CompanyService.java │ │ └── filter │ │ └── MinifyFilter.java └── test │ ├── java │ └── com │ │ └── horyu1234 │ │ └── eventangel │ │ └── EventAngelApplicationTests.java │ └── resource │ └── application.default.yml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── assets ├── EventAngel-DatabaseStruct v1.6.0.PNG ├── EventAngel-DatabaseStruct v1.7.0.PNG ├── EventAngel-DatabaseStruct v1.8.0.PNG └── EventAngel-DatabaseStruct v1.9.0.PNG ├── LICENSE.md ├── .gitignore ├── README.md └── gradlew.bat /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'EventAngel' 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | before_install: 5 | - chmod +x gradlew -------------------------------------------------------------------------------- /src/main/resources/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/favicon.ico -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/static/img/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/img/logo.jpg -------------------------------------------------------------------------------- /src/main/resources/static/naver0110416977c450401d78ac7e3daa0f31.html: -------------------------------------------------------------------------------- 1 | naver-site-verification: naver0110416977c450401d78ac7e3daa0f31.html -------------------------------------------------------------------------------- /assets/EventAngel-DatabaseStruct v1.6.0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/assets/EventAngel-DatabaseStruct v1.6.0.PNG -------------------------------------------------------------------------------- /assets/EventAngel-DatabaseStruct v1.7.0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/assets/EventAngel-DatabaseStruct v1.7.0.PNG -------------------------------------------------------------------------------- /assets/EventAngel-DatabaseStruct v1.8.0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/assets/EventAngel-DatabaseStruct v1.8.0.PNG -------------------------------------------------------------------------------- /assets/EventAngel-DatabaseStruct v1.9.0.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/assets/EventAngel-DatabaseStruct v1.9.0.PNG -------------------------------------------------------------------------------- /src/main/resources/static/img/error_404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/img/error_404.png -------------------------------------------------------------------------------- /src/main/resources/static/img/error_500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/img/error_500.png -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWeb.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWeb.eot -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWeb.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWeb.ttf -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWeb.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWeb.woff -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWebBold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWebBold.eot -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWebBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWebBold.ttf -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWebBold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWebBold.woff -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWebLight.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWebLight.eot -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWebLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWebLight.ttf -------------------------------------------------------------------------------- /src/main/resources/static/webfonts/NanumBarunGothicWebLight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/webfonts/NanumBarunGothicWebLight.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/horyu1234/EventAngel/HEAD/src/main/resources/static/lib/fontawesome-free-5.0.9/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/js/layout.min.js: -------------------------------------------------------------------------------- 1 | moment.locale("ko");Sugar.extend();window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments)}gtag("js",new Date);gtag("config","UA-75680482-7"); 2 | //# sourceMappingURL=layout.min.js.map -------------------------------------------------------------------------------- /src/main/resources/static/css/apply.min.css: -------------------------------------------------------------------------------- 1 | #event-title{font-weight:bold;font-size:28pt}#event-detail{font-weight:bold;font-size:15pt;color:gray}#subscribe-notice-title{font-weight:bold;font-size:18pt;margin-bottom:0}#subscribe-notice-detail{font-size:10pt} -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/constant/EventStatus.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.constant; 2 | 3 | /** 4 | * Created by horyu on 2018-04-11 5 | */ 6 | public enum EventStatus { 7 | OPEN, 8 | CLOSE, 9 | LOTTERY 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/apply/invalidForm.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이메일 또는 유튜브 닉네임란이 비어있거나, 올바르지 않은 이메일 주소입니다. 5 |
6 |
7 |
-------------------------------------------------------------------------------- /src/main/resources/templates/view/check/notOpenEvent.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이벤트 응모가 진행 중일 경우에만 응모 여부를 확인하실 수 있습니다. 5 |
6 |
7 |
-------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Jun 19 18:31:38 KST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip 7 | -------------------------------------------------------------------------------- /src/main/resources/static/js/layout.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | moment.locale('ko'); 4 | Sugar.extend(); 5 | 6 | window.dataLayer = window.dataLayer || []; 7 | 8 | function gtag() { 9 | dataLayer.push(arguments); 10 | } 11 | 12 | gtag('js', new Date()); 13 | gtag('config', 'UA-75680482-7'); -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/constant/EventDetailStatus.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.constant; 2 | 3 | /** 4 | * Created by horyu on 2018-04-14 5 | */ 6 | public enum EventDetailStatus { 7 | START_SOON, 8 | ALREADY_END, 9 | OPEN, 10 | CLOSE, 11 | LOTTERY 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/apply/alreadyEnd.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이미 응모 신청이 마감되었습니다. 5 |

6 | 아쉽지만 다음 이벤트를 기대해주세요! 7 |
8 |
9 |
-------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## License 2 | Copyright 2018. horyu1234(류현오) All rights reserved. 3 | 4 | --- 5 | 6 | 본 프로젝트의 소스는 이용자 본인의 학습 용도로만 사용하는 것을 허용하며, 영리추구, 운영 등등 원 저작자의 허락을 받지 않은 모든 행위는 저작권법에 의거하여 엄격히 금지합니다. 7 | 8 | 본 프로젝트의 원 저작권자는 소프트웨어에 관해서 어떠한 종류의 책임도 지지 않습니다. 9 | 10 | --- 11 | 12 | 본 프로젝트에 기여하고 싶으시다면 Pull Request 기능을 이용해주시기 바랍니다. 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/check/notExistApply.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이벤트 응모가 되어 있지 않습니다. 5 |
6 | 7 | 이벤트 응모 (클릭) 8 |
9 |
-------------------------------------------------------------------------------- /src/main/resources/templates/view/failReCaptcha.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | ReCaptcha 인증에 실패하였습니다 5 |

6 | 이전 화면에서 다시 시도해주세요. 7 |
8 |
9 |
-------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/config/HttpSessionConfig.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession; 5 | 6 | @Configuration 7 | @EnableJdbcHttpSession 8 | public class HttpSessionConfig { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/component/companyGiftTable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 |
10 |
-------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.Login.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{};Horyu.View.Login=function(){var a=this;a.init=function(){a.bindEvents()};a.bindEvents=function(){$(".loginBtn").click(function(){grecaptcha.execute()})};return{init:function(){a.init()}}};function onReCaptchaCallback(){$("#loginForm").submit()}; 2 | //# sourceMappingURL=Horyu.View.Login.min.js.map -------------------------------------------------------------------------------- /src/main/resources/static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "허수아비 이벤트", 3 | "name": "허수아비 이벤트", 4 | "icons": [ 5 | { 6 | "src": "img/logo.jpg", 7 | "type": "image/jpg", 8 | "sizes": "176x176" 9 | } 10 | ], 11 | "start_url": "/", 12 | "theme_color": "#373a3c", 13 | "background_color": "#2196f3", 14 | "orientation": "portrait", 15 | "display": "standalone" 16 | } -------------------------------------------------------------------------------- /src/main/resources/templates/view/error/404.html: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 |
14 | 메인 페이지로 15 |
-------------------------------------------------------------------------------- /src/main/resources/templates/view/error/500.html: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 |
14 | 메인 페이지로 15 |
-------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/EventAngelApplication.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | //@EnableCaching 7 | @SpringBootApplication 8 | public class EventAngelApplication { 9 | 10 | public static void main(String[] args) { 11 | SpringApplication.run(EventAngelApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/form/CheckForm.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.form; 2 | 3 | import javax.validation.constraints.NotNull; 4 | 5 | /** 6 | * Created by horyu on 2018-04-03 7 | */ 8 | public class CheckForm { 9 | @NotNull 10 | private String email; 11 | 12 | public String getEmail() { 13 | return email; 14 | } 15 | 16 | public void setEmail(String email) { 17 | this.email = email; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | ______ _ _ 2 | | ____| | | /\ | | 3 | | |____ _____ _ __ | |_ / \ _ __ __ _ ___| | 4 | | __\ \ / / _ \ '_ \| __| / /\ \ | '_ \ / _` |/ _ \ | 5 | | |___\ V / __/ | | | |_ / ____ \| | | | (_| | __/ | 6 | |______\_/ \___|_| |_|\__/_/ \_\_| |_|\__, |\___|_| 7 | __/ | 8 | |___/ -------------------------------------------------------------------------------- /src/main/resources/static/js/layout.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"layout.min.js", 4 | "lineCount":1, 5 | "mappings":"AAEAA,MAAAC,OAAA,CAAc,IAAd,CACAC,MAAAC,OAAA,EAEAC,OAAAC,UAAA,CAAmBD,MAAAC,UAAnB,EAAuC,EAEvCC,SAASA,KAAI,EAAG,CACZD,SAAAE,KAAA,CAAeC,SAAf,CADY,CAIhBF,IAAA,CAAK,IAAL,CAAW,IAAIG,IAAf,CACAH,KAAA,CAAK,QAAL,CAAe,eAAf;", 6 | "sources":["/js/layout.js"], 7 | "names":["moment","locale","Sugar","extend","window","dataLayer","gtag","push","arguments","Date"] 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/factory/SessionAttributeNameFactory.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.factory; 2 | 3 | /** 4 | * Created by horyu on 2018-04-07 5 | */ 6 | public class SessionAttributeNameFactory { 7 | public static final String LOGIN_USERNAME = "loginUsername"; 8 | public static final String LOGIN_NICKNAME = "loginNickname"; 9 | 10 | private SessionAttributeNameFactory() { 11 | throw new IllegalStateException("Factory class"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /build/ 3 | /out/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | nbproject/private/ 23 | nbbuild/ 24 | dist/ 25 | nbdist/ 26 | .nb-gradle/ 27 | 28 | /src/main/resources/application.yml 29 | /src/test/resource/application.yml 30 | /uploadDir 31 | *.p12 -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventHistoryView.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{};Horyu.View.EventHistoryView=function(b){var a=this;a.options=$.extend({companyGiftData:[],eventWinnerData:[]},b);a.init=function(){a.companyGiftTable=new Horyu.View.CompanyGiftTable;a.companyGiftTable.init();a.companyGiftTable.updateTable(a.options.companyGiftData,a.options.eventWinnerData)};return{init:function(){a.init()}}}; 2 | //# sourceMappingURL=Horyu.View.EventHistoryView.min.js.map -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | /** 8 | * Created by horyu on 2018-04-02 9 | */ 10 | @Controller 11 | public class HomeController { 12 | @RequestMapping("/") 13 | public String home() { 14 | return View.APPLY.toRedirect(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/horyu1234/eventangel/EventAngelApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel; 2 | 3 | import org.junit.Ignore; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | public class EventAngelApplicationTests { 12 | 13 | @Test 14 | @Ignore 15 | public void contextLoads() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/apply/success.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이벤트 응모가 완료되었습니다. 5 |

6 | 응모 일자: 7 |
8 | 유튜브 닉네임: 9 |
10 | 이메일: 11 |
12 |
13 |
-------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/factory/DateFactory.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.factory; 2 | 3 | import java.time.format.DateTimeFormatter; 4 | 5 | public class DateFactory { 6 | public static final DateTimeFormatter PRETTY_FORMAT = DateTimeFormatter.ofPattern("yyyy년MM월dd일 a hh시mm분ss초"); 7 | public static final DateTimeFormatter DATABASE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"); 8 | 9 | private DateFactory() { 10 | throw new IllegalStateException("Factory class"); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/check/existApply.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이벤트 응모가 되어 있는 상태입니다. 5 |

6 | 응모 일자: 7 |
8 | 유튜브 닉네임: 9 |
10 | 이메일: 11 |
12 |
13 |
-------------------------------------------------------------------------------- /src/main/resources/templates/view/apply/reduplication.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 이미 동일 이메일로 이벤트 응모를 하셨습니다. 5 |

6 | 응모 일자: 7 |
8 | 유튜브 닉네임: 9 |
10 | 이메일: 11 |
12 |
13 |
-------------------------------------------------------------------------------- /src/main/resources/templates/view/apply/failReCaptcha.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 자동화 응모를 방지하기 위한 인증에 실패하였습니다. 5 |

6 | 응모 화면에서 다시 시도해주세요. 7 |

8 | (ReCaptcha 인증에 실패하였습니다) 9 |
10 | 11 | 응모 화면으로 (클릭) 12 |
13 |
-------------------------------------------------------------------------------- /src/test/resource/application.default.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level.org.springframework.jdbc.core.JdbcTemplate: debug 3 | 4 | server: 5 | port: 9093 6 | 7 | spring: 8 | session: 9 | store-type: jdbc 10 | thymeleaf: 11 | cache: false 12 | datasource: 13 | driver-class-name: com.mysql.jdbc.Driver 14 | url: jdbc:mysql://:/ 15 | username: 16 | password: 17 | validation-query: SELECT 1 18 | test-while-idle: true 19 | max-active: 200 20 | max-idle: 100 21 | min-idle: 20 22 | max-wait: 1000 -------------------------------------------------------------------------------- /src/main/resources/static/js/Horyu.View.Check.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{};Horyu.View.Check=function(){var a=this;a.init=function(){a.initParsley();a.bindEvents()};a.initParsley=function(){$("#checkForm").parsley({successClass:"is-valid",errorClass:"is-invalid",classHandler:function(a){return a.$element.closest("input")}})};a.bindEvents=function(){$(".submitBtn").click(function(){$("#checkForm").parsley().validate()&&grecaptcha.execute()})};return{init:function(){a.init()}}}; 2 | function onReCaptchaCallback(){$("#checkForm").submit()}; 3 | //# sourceMappingURL=Horyu.View.Check.min.js.map -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/config/MinifyConfig.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.config; 2 | 3 | import com.horyu1234.eventangel.filter.MinifyFilter; 4 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * Created by horyu on 2018-01-15 10 | */ 11 | @Configuration 12 | public class MinifyConfig { 13 | @Bean 14 | public FilterRegistrationBean getFilterRegistrationBean() { 15 | return new FilterRegistrationBean<>(new MinifyFilter()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/static/css/admin.min.css: -------------------------------------------------------------------------------- 1 | .container-full{margin:0 auto;width:100%}.applicant-list-table .apply-time{min-width:185px}.applicant-list-table .apply-email{min-width:200px}.applicant-list-table .apply-youtubeNickname{min-width:150px}.applicant-list-table .apply-ipAddress{min-width:100px}.applicant-list-table .apply-referer{min-width:100px}.applicant-list-table .apply-userAgent{min-width:300px}.applicant-list-table .apply-fingerprint2{min-width:150px}.applicant-list-table .apply-duplicated{min-width:50px}.applicant-list-table .apply-dupCheckAdminName{min-width:50px}.duplicated-table .duplicated-count{width:100px}.duplicated-table .remarks{width:200px} -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.Login.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Horyu = window.Horyu || {}; 4 | Horyu.View = window.Horyu.View || {}; 5 | Horyu.View.Login = function() { 6 | var _this = this; 7 | 8 | _this.init = function() { 9 | _this.bindEvents(); 10 | }; 11 | 12 | _this.bindEvents = function() { 13 | $('.loginBtn').click(function() { 14 | grecaptcha.execute(); 15 | }); 16 | }; 17 | 18 | return { 19 | init: function() { 20 | _this.init(); 21 | } 22 | }; 23 | }; 24 | 25 | function onReCaptchaCallback() { 26 | $('#loginForm').submit(); 27 | } -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/DuplicatedApplicant.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | public class DuplicatedApplicant { 4 | private String columnName; 5 | private int duplicatedCount; 6 | 7 | public String getColumnName() { 8 | return columnName; 9 | } 10 | 11 | public void setColumnName(String columnName) { 12 | this.columnName = columnName; 13 | } 14 | 15 | public int getDuplicatedCount() { 16 | return duplicatedCount; 17 | } 18 | 19 | public void setDuplicatedCount(int duplicatedCount) { 20 | this.duplicatedCount = duplicatedCount; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/static/css/apply.css: -------------------------------------------------------------------------------- 1 | #event-title { 2 | font-weight: bold; 3 | font-size: 28pt; 4 | } 5 | 6 | #event-detail { 7 | font-weight: bold; 8 | font-size: 15pt; 9 | color: gray; 10 | } 11 | 12 | #subscribe-notice-title { 13 | font-weight: bold; 14 | font-size: 18pt; 15 | margin-bottom: 0; 16 | } 17 | 18 | #subscribe-notice-detail { 19 | font-size: 10pt; 20 | } 21 | 22 | .step-text { 23 | margin-bottom: 0; 24 | font-size: 14pt; 25 | } 26 | 27 | .step-text strong { 28 | color: #EF5350; 29 | } 30 | 31 | .step-img { 32 | margin-bottom: 30px; 33 | max-width: 60%; 34 | max-height: 60%; 35 | } -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/css/fa-brands.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:Font Awesome\ 5 Brands} -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/css/fa-solid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:Font Awesome\ 5 Free;font-weight:900} -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/css/fa-regular.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-family:Font Awesome\ 5 Free;font-weight:400} -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/form/LoginForm.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.form; 2 | 3 | import javax.validation.constraints.NotNull; 4 | 5 | /** 6 | * Created by horyu on 2018-04-03 7 | */ 8 | public class LoginForm { 9 | @NotNull 10 | private String username; 11 | 12 | @NotNull 13 | private String password; 14 | 15 | public String getUsername() { 16 | return username; 17 | } 18 | 19 | public void setUsername(String username) { 20 | this.username = username; 21 | } 22 | 23 | public String getPassword() { 24 | return password; 25 | } 26 | 27 | public void setPassword(String password) { 28 | this.password = password; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/PrivacyController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | 9 | /** 10 | * Created by horyu on 2018-05-30. 11 | */ 12 | @Controller 13 | public class PrivacyController { 14 | @RequestMapping("/privacy") 15 | public String home(Model model) { 16 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.PRIVACY.toView()); 17 | 18 | return View.LAYOUT.getTemplateName(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/admin/eventHistoryView.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EventAngel 2 | [![Build Status](https://travis-ci.org/horyu1234/EventAngel.svg?branch=master)](https://travis-ci.org/horyu1234/EventAngel) 3 | [![works badge](https://cdn.rawgit.com/nikku/works-on-my-machine/v0.2.0/badge.svg)](https://github.com/nikku/works-on-my-machine) 4 | 5 | 허수아비 이벤트 사이트입니다. 6 | 공정성을 위하여 사이트 소스 전체를 공개합니다. 7 | 8 | 9 | ### 어플리케이션 실행 환경 10 | - Java 8 이상 11 | - MariaDB 12 | 13 | 14 | ### 데이터베이스 구조 15 | ![works badge](https://raw.githubusercontent.com/horyu1234/EventAngel/master/assets/EventAngel-DatabaseStruct%20v1.9.0.PNG) 16 | 17 | 18 | --- 19 | 20 | 프로그램 소스 사용은 [라이선스](https://github.com/horyu1234/EventAngel/blob/master/LICENSE.md)를 반드시 확인해주세요. 21 | 프로그램에 버그 또는 문제가 있다면 [이슈 생성](https://github.com/horyu1234/EventAngel/issues/new) 으로 제보 부탁드립니다. 22 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/css/fa-brands.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Brands'; 7 | font-style: normal; 8 | font-weight: normal; 9 | src: url("../webfonts/fa-brands-400.eot"); 10 | src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } 11 | 12 | .fab { 13 | font-family: 'Font Awesome 5 Brands'; } 14 | -------------------------------------------------------------------------------- /src/main/resources/static/css/style.min.css: -------------------------------------------------------------------------------- 1 | #main-container{margin-top:20px;margin-bottom:100px}.hidden-input{visibility:hidden}.invalid-feedback{font-size:13pt !important}.company-gift-table{min-width:800px}.company-gift-table td{vertical-align:middle}.company-gift-table .company-cell{min-width:300px}.company-gift-table .gift-cell{min-width:200px}.company-gift-table .event-winner-pending-cell{color:#9e9e9e !important}.company-gift-table .event-winner-cell{color:#0043ff !important;font-weight:bold}#copyright{text-align:center;width:100%;position:fixed;bottom:0;margin-bottom:0;font-weight:bold;padding-bottom:2px;padding-top:2px;z-index:1000}.table-responsive{border-left:1px solid #ddd !important;border-right:1px solid #ddd !important;border-bottom:1px solid #ddd !important}.company-logo{max-width:150px;height:auto} -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventHistoryView.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Horyu = window.Horyu || {}; 4 | Horyu.View = window.Horyu.View || {}; 5 | Horyu.View.EventHistoryView = function(options) { 6 | var _this = this; 7 | 8 | var defaultOptions = { 9 | companyGiftData: [], 10 | eventWinnerData: [] 11 | }; 12 | 13 | _this.options = $.extend(defaultOptions, options); 14 | 15 | _this.init = function() { 16 | _this.companyGiftTable = new Horyu.View.CompanyGiftTable(); 17 | _this.companyGiftTable.init(); 18 | 19 | _this.companyGiftTable.updateTable(_this.options.companyGiftData, _this.options.eventWinnerData); 20 | }; 21 | 22 | return { 23 | init: function() { 24 | _this.init(); 25 | } 26 | }; 27 | }; -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/css/fa-solid.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 900; 9 | src: url("../webfonts/fa-solid-900.eot"); 10 | src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } 11 | 12 | .fa, 13 | .fas { 14 | font-family: 'Font Awesome 5 Free'; 15 | font-weight: 900; } 16 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/fontawesome-free-5.0.9/css/fa-regular.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com 3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) 4 | */ 5 | @font-face { 6 | font-family: 'Font Awesome 5 Free'; 7 | font-style: normal; 8 | font-weight: 400; 9 | src: url("../webfonts/fa-regular-400.eot"); 10 | src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } 11 | 12 | .far { 13 | font-family: 'Font Awesome 5 Free'; 14 | font-weight: 400; } 15 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/CharResponseWrapper.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel; 2 | 3 | import javax.servlet.http.HttpServletResponse; 4 | import javax.servlet.http.HttpServletResponseWrapper; 5 | import java.io.CharArrayWriter; 6 | import java.io.PrintWriter; 7 | 8 | /** 9 | * Created by horyu on 2018-01-15 10 | */ 11 | public class CharResponseWrapper extends HttpServletResponseWrapper { 12 | private final CharArrayWriter output = new CharArrayWriter(); 13 | 14 | public CharResponseWrapper(HttpServletResponse response) { 15 | super(response); 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return output.toString(); 21 | } 22 | 23 | @Override 24 | public PrintWriter getWriter() { 25 | return new PrintWriter(output); 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.Login.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"Horyu.View.Login.min.js", 4 | "lineCount":1, 5 | "mappings":"AAEA,IAAIA,MAAQC,MAAAD,MAARA,EAAwB,EAC5BA,MAAAE,KAAA,CAAaD,MAAAD,MAAAE,KAAb,EAAkC,EAClCF,MAAAE,KAAAC,MAAA,CAAmBC,QAAQ,EAAG,CAC1B,IAAIC,EAAQ,IAEZA,EAAAC,KAAA,CAAaC,QAAQ,EAAG,CACpBF,CAAAG,WAAA,EADoB,CAIxBH,EAAAG,WAAA,CAAmBC,QAAQ,EAAG,CAC1BC,CAAA,CAAE,WAAF,CAAAC,MAAA,CAAqB,QAAQ,EAAG,CAC5BC,UAAAC,QAAA,EAD4B,CAAhC,CAD0B,CAM9B,OAAO,CACHP,KAAMA,QAAQ,EAAG,CACbD,CAAAC,KAAA,EADa,CADd,CAbmB,CAoB9BQ,SAASA,oBAAmB,EAAG,CAC3BJ,CAAA,CAAE,YAAF,CAAAK,OAAA,EAD2B;", 6 | "sources":["/js/admin/Horyu.View.Login.js"], 7 | "names":["Horyu","window","View","Login","Horyu.View.Login","_this","init","_this.init","bindEvents","_this.bindEvents","$","click","grecaptcha","execute","onReCaptchaCallback","submit"] 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/Account.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | /** 4 | * Created by horyu on 2018-04-03 5 | */ 6 | public class Account { 7 | private String username; 8 | private String password; 9 | private String nickname; 10 | 11 | public String getUsername() { 12 | return username; 13 | } 14 | 15 | public void setUsername(String username) { 16 | this.username = username; 17 | } 18 | 19 | public String getPassword() { 20 | return password; 21 | } 22 | 23 | public void setPassword(String password) { 24 | this.password = password; 25 | } 26 | 27 | public String getNickname() { 28 | return nickname; 29 | } 30 | 31 | public void setNickname(String nickname) { 32 | this.nickname = nickname; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/factory/ModelAttributeNameFactory.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.factory; 2 | 3 | /** 4 | * Created by horyu on 2018-04-07 5 | */ 6 | public class ModelAttributeNameFactory { 7 | public static final String VIEW_NAME = "viewName"; 8 | 9 | public static final String LOGIN_USERNAME = "username"; 10 | 11 | public static final String EVENT_ID = "eventId"; 12 | public static final String EVENT_STATUS = "eventStatus"; 13 | public static final String EVENT_TITLE = "eventTitle"; 14 | public static final String EVENT_DETAIL = "eventDetail"; 15 | public static final String EVENT_START_TIME = "eventStartTime"; 16 | public static final String EVENT_END_TIME = "eventEndTime"; 17 | 18 | private ModelAttributeNameFactory() { 19 | throw new IllegalStateException("Factory class"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/DuplicatedController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.PathVariable; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | @RequestMapping("/admin/duplicated") 12 | @Controller 13 | public class DuplicatedController { 14 | @RequestMapping(value = "/", method = RequestMethod.GET) 15 | public String duplicated(Model model) { 16 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_DUPLICATED.toView()); 17 | 18 | return View.LAYOUT.getTemplateName(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/mapper/CompanyMapper.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.mapper; 2 | 3 | import com.horyu1234.eventangel.domain.Company; 4 | import org.springframework.jdbc.core.RowMapper; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | 10 | @Component 11 | public class CompanyMapper implements RowMapper { 12 | @Override 13 | public Company mapRow(ResultSet rs, int rowNum) throws SQLException { 14 | Company company = new Company(); 15 | company.setEventId(rs.getInt("EVENT_ID")); 16 | company.setCompanyId(rs.getInt("COMPANY_ID")); 17 | company.setCompanyName(rs.getString("COMPANY_NAME")); 18 | company.setCompanyDetail(rs.getString("COMPANY_DETAIL")); 19 | company.setCompanyLogoImageFileName(rs.getString("COMP_LOGO_IMG_FNAME")); 20 | 21 | return company; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventHistoryView.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"Horyu.View.EventHistoryView.min.js", 4 | "lineCount":1, 5 | "mappings":"AAEA,IAAIA,MAAQC,MAAAD,MAARA,EAAwB,EAC5BA,MAAAE,KAAA,CAAaD,MAAAD,MAAAE,KAAb,EAAkC,EAClCF,MAAAE,KAAAC,iBAAA,CAA8BC,QAAQ,CAACC,CAAD,CAAU,CAC5C,IAAIC,EAAQ,IAOZA,EAAAD,QAAA,CAAgBE,CAAAC,OAAA,CALKC,CACjBC,gBAAiB,EADAD,CAEjBE,gBAAiB,EAFAF,CAKL,CAAyBJ,CAAzB,CAEhBC,EAAAM,KAAA,CAAaC,QAAQ,EAAG,CACpBP,CAAAQ,iBAAA,CAAyB,IAAId,KAAAE,KAAAa,iBAC7BT,EAAAQ,iBAAAF,KAAA,EAEAN,EAAAQ,iBAAAE,YAAA,CAAmCV,CAAAD,QAAAK,gBAAnC,CAAkEJ,CAAAD,QAAAM,gBAAlE,CAJoB,CAOxB,OAAO,CACHC,KAAMA,QAAQ,EAAG,CACbN,CAAAM,KAAA,EADa,CADd,CAjBqC;", 6 | "sources":["/js/admin/Horyu.View.EventHistoryView.js"], 7 | "names":["Horyu","window","View","EventHistoryView","Horyu.View.EventHistoryView","options","_this","$","extend","defaultOptions","companyGiftData","eventWinnerData","init","_this.init","companyGiftTable","CompanyGiftTable","updateTable"] 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/static/css/admin.css: -------------------------------------------------------------------------------- 1 | .container-full { 2 | margin: 0 auto; 3 | width: 100%; 4 | } 5 | 6 | .applicant-list-table .apply-time { 7 | min-width: 185px; 8 | } 9 | 10 | .applicant-list-table .apply-email { 11 | min-width: 200px; 12 | } 13 | 14 | .applicant-list-table .apply-youtubeNickname { 15 | min-width: 150px; 16 | } 17 | 18 | .applicant-list-table .apply-ipAddress { 19 | min-width: 100px; 20 | } 21 | 22 | .applicant-list-table .apply-referer { 23 | min-width: 100px; 24 | } 25 | 26 | .applicant-list-table .apply-userAgent { 27 | min-width: 300px; 28 | } 29 | 30 | .applicant-list-table .apply-fingerprint2 { 31 | min-width: 150px; 32 | } 33 | 34 | .applicant-list-table .apply-duplicated { 35 | min-width: 50px; 36 | } 37 | 38 | .applicant-list-table .apply-dupCheckAdminName { 39 | min-width: 50px; 40 | } 41 | 42 | .duplicated-table .duplicated-count { 43 | width: 100px; 44 | } 45 | 46 | .duplicated-table .remarks { 47 | width: 200px; 48 | } -------------------------------------------------------------------------------- /src/main/resources/templates/view/admin/eventHistory.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
#이벤트 명이벤트 세부일정이벤트 상태이벤트 시작 시간이벤트 종료 시간이벤트 응모 수이벤트 결과 확인
19 |
20 | 21 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/form/CompanySaveForm.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.form; 2 | 3 | import javax.validation.constraints.NotNull; 4 | 5 | /** 6 | * Created by horyu on 2018-04-13 7 | */ 8 | public class CompanySaveForm { 9 | @NotNull 10 | private int companyId; 11 | 12 | @NotNull 13 | private String companyName; 14 | 15 | @NotNull 16 | private String companyDetail; 17 | 18 | public int getCompanyId() { 19 | return companyId; 20 | } 21 | 22 | public void setCompanyId(int companyId) { 23 | this.companyId = companyId; 24 | } 25 | 26 | public String getCompanyName() { 27 | return companyName; 28 | } 29 | 30 | public void setCompanyName(String companyName) { 31 | this.companyName = companyName; 32 | } 33 | 34 | public String getCompanyDetail() { 35 | return companyDetail; 36 | } 37 | 38 | public void setCompanyDetail(String companyDetail) { 39 | this.companyDetail = companyDetail; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/interceptor/AuthenticationInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.interceptor; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.factory.SessionAttributeNameFactory; 5 | import org.springframework.stereotype.Component; 6 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | @Component 12 | public class AuthenticationInterceptor extends HandlerInterceptorAdapter { 13 | @Override 14 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 15 | String loginUsername = (String) request.getSession().getAttribute(SessionAttributeNameFactory.LOGIN_USERNAME); 16 | if (loginUsername == null) { 17 | response.sendRedirect(View.ADMIN_LOGIN.toPath()); 18 | return false; 19 | } 20 | 21 | return true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/form/ApplyForm.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.form; 2 | 3 | import javax.validation.constraints.NotNull; 4 | import javax.validation.constraints.Null; 5 | 6 | /** 7 | * Created by horyu on 2018-04-03 8 | */ 9 | public class ApplyForm { 10 | @NotNull 11 | private String youtubeNickname; 12 | 13 | @NotNull 14 | private String email; 15 | 16 | @Null 17 | private String fingerprint2; 18 | 19 | public String getYoutubeNickname() { 20 | return youtubeNickname; 21 | } 22 | 23 | public void setYoutubeNickname(String youtubeNickname) { 24 | this.youtubeNickname = youtubeNickname; 25 | } 26 | 27 | public String getEmail() { 28 | return email; 29 | } 30 | 31 | public void setEmail(String email) { 32 | this.email = email; 33 | } 34 | 35 | public String getFingerprint2() { 36 | return fingerprint2; 37 | } 38 | 39 | public void setFingerprint2(String fingerprint2) { 40 | this.fingerprint2 = fingerprint2; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/mapper/EventWinnerMapper.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.mapper; 2 | 3 | import com.horyu1234.eventangel.domain.EventWinner; 4 | import com.horyu1234.eventangel.factory.DateFactory; 5 | import org.springframework.jdbc.core.RowMapper; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.sql.ResultSet; 9 | import java.sql.SQLException; 10 | import java.time.LocalDateTime; 11 | 12 | /** 13 | * Created by horyu on 2018-06-17. 14 | */ 15 | @Component 16 | public class EventWinnerMapper implements RowMapper { 17 | @Override 18 | public EventWinner mapRow(ResultSet rs, int rowNum) throws SQLException { 19 | EventWinner eventWinner = new EventWinner(); 20 | eventWinner.setEventId(rs.getInt("EVENT_ID")); 21 | eventWinner.setPrizeId(rs.getInt("PRIZE_ID")); 22 | eventWinner.setApplyEmail(rs.getString("APPLY_EMAIL")); 23 | eventWinner.setWinTime(LocalDateTime.parse(rs.getString("WIN_TIME"), DateFactory.DATABASE_FORMAT)); 24 | 25 | return eventWinner; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/EventWinner.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | /** 6 | * Created by horyu on 2018-04-16 7 | */ 8 | public class EventWinner { 9 | private int eventId; 10 | private int prizeId; 11 | private String applyEmail; 12 | private LocalDateTime winTime; 13 | 14 | public int getEventId() { 15 | return eventId; 16 | } 17 | 18 | public void setEventId(int eventId) { 19 | this.eventId = eventId; 20 | } 21 | 22 | public int getPrizeId() { 23 | return prizeId; 24 | } 25 | 26 | public void setPrizeId(int prizeId) { 27 | this.prizeId = prizeId; 28 | } 29 | 30 | public String getApplyEmail() { 31 | return applyEmail; 32 | } 33 | 34 | public void setApplyEmail(String applyEmail) { 35 | this.applyEmail = applyEmail; 36 | } 37 | 38 | public LocalDateTime getWinTime() { 39 | return winTime; 40 | } 41 | 42 | public void setWinTime(LocalDateTime winTime) { 43 | this.winTime = winTime; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/resources/static/css/font.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:'NanumBarunGothic';font-style:normal;font-weight:400;src:url('../webfonts/NanumBarunGothicWeb.eot');src:url('../webfonts/NanumBarunGothicWeb.eot?#iefix') format('embedded-opentype'),url('../webfonts/NanumBarunGothicWeb.woff') format('woff'),url('../webfonts/NanumBarunGothicWeb.ttf') format('truetype')}@font-face{font-family:'NanumBarunGothic';font-style:normal;font-weight:700;src:url('../webfonts/NanumBarunGothicWebBold.eot');src:url('../webfonts/NanumBarunGothicWebBold.eot?#iefix') format('embedded-opentype'),url('../webfonts/NanumBarunGothicWebBold.woff') format('woff'),url('../webfonts/NanumBarunGothicWebBold.ttf') format('truetype')}@font-face{font-family:'NanumBarunGothic';font-style:normal;font-weight:300;src:url('../webfonts/NanumBarunGothicWebLight.eot');src:url('../webfonts/NanumBarunGothicWebLight.eot?#iefix') format('embedded-opentype'),url('../webfonts/NanumBarunGothicWebLight.woff') format('woff'),url('../webfonts/NanumBarunGothicWebLight.ttf') format('truetype')}html,body,h1,h2,h3,h4,h5,h6,li,p,a,div,option,label,span{font-family:'NanumBarunGothic',sans-serif !important} -------------------------------------------------------------------------------- /src/main/resources/static/js/Horyu.View.Check.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Horyu = window.Horyu || {}; 4 | Horyu.View = window.Horyu.View || {}; 5 | Horyu.View.Check = function() { 6 | var _this = this; 7 | 8 | _this.init = function() { 9 | _this.initParsley(); 10 | _this.bindEvents(); 11 | }; 12 | 13 | _this.initParsley = function() { 14 | $("#checkForm").parsley({ 15 | successClass: "is-valid", 16 | errorClass: "is-invalid", 17 | classHandler: function(element) { 18 | return element.$element.closest("input"); 19 | } 20 | }); 21 | }; 22 | 23 | _this.bindEvents = function() { 24 | $('.submitBtn').click(function() { 25 | var isFormValidate = $('#checkForm').parsley().validate(); 26 | if (isFormValidate) { 27 | grecaptcha.execute(); 28 | } 29 | }); 30 | }; 31 | 32 | return { 33 | init: function() { 34 | _this.init(); 35 | } 36 | }; 37 | }; 38 | 39 | function onReCaptchaCallback() { 40 | $('#checkForm').submit(); 41 | } -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/rest/LotteryRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin.rest; 2 | 3 | import com.horyu1234.eventangel.domain.Applicant; 4 | import com.horyu1234.eventangel.service.LotteryService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestMethod; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | /** 11 | * Created by horyu on 2018-04-16 12 | */ 13 | @RequestMapping("/admin/lottery") 14 | @RestController 15 | public class LotteryRestController { 16 | private LotteryService lotteryService; 17 | 18 | @Autowired 19 | public void setLotteryService(LotteryService lotteryService) { 20 | this.lotteryService = lotteryService; 21 | } 22 | 23 | @RequestMapping(value = "/lottery", method = RequestMethod.POST) 24 | public Applicant lottery(int prizeId) { 25 | Applicant applicant = lotteryService.lottery(prizeId); 26 | applicant.hidePrivacy(); 27 | 28 | return applicant; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/parsley-2.8.1/i18n/ko.js: -------------------------------------------------------------------------------- 1 | // Validation errors messages for Parsley 2 | // Load this after Parsley 3 | 4 | Parsley.addMessages('ko', { 5 | defaultMessage: "입력하신 내용이 올바르지 않습니다.", 6 | type: { 7 | email: "입력하신 이메일이 유효하지 않습니다.", 8 | url: "입력하신 URL이 유효하지 않습니다.", 9 | number: "입력하신 전화번호가 올바르지 않습니다.", 10 | integer: "입력하신 정수가 유효하지 않습니다.", 11 | digits: "숫자를 입력하여 주십시오.", 12 | alphanum: "입력하신 내용은 알파벳과 숫자의 조합이어야 합니다." 13 | }, 14 | notblank: "공백은 입력하실 수 없습니다.", 15 | required: "필수 입력사항입니다.", 16 | pattern: "입력하신 내용이 올바르지 않습니다.", 17 | min: "입력하신 내용이 %s보다 크거나 같아야 합니다. ", 18 | max: "입력하신 내용이 %s보다 작거나 같아야 합니다.", 19 | range: "입력하신 내용이 %s보다 크고 %s 보다 작아야 합니다.", 20 | minlength: "%s 이상의 글자수를 입력하십시오. ", 21 | maxlength: "%s 이하의 글자수를 입력하십시오. ", 22 | length: "입력하신 내용의 글자수가 %s보다 크고 %s보다 작아야 합니다.", 23 | mincheck: "최소한 %s개를 선택하여 주십시오. ", 24 | maxcheck: "%s개 또는 그보다 적게 선택하여 주십시오.", 25 | check: "선택하신 내용이 %s보다 크거나 %s보다 작아야 합니다.", 26 | equalto: "같은 값을 입력하여 주십시오." 27 | }); 28 | 29 | Parsley.setLocale('ko'); 30 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/ApplicantListController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestParam; 9 | 10 | @RequestMapping("/admin/applicantList") 11 | @Controller 12 | public class ApplicantListController { 13 | @RequestMapping("/") 14 | public String applicantList(Model model, 15 | @RequestParam(required = false) String columnId, 16 | @RequestParam(required = false) String columnName) { 17 | if (columnId != null && columnName != null) { 18 | model.addAttribute("columnId", columnId); 19 | model.addAttribute("columnName", columnName); 20 | } 21 | 22 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_APPLICANT_LIST.toView()); 23 | 24 | return View.LAYOUT.getTemplateName(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/static/js/Horyu.View.Check.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"Horyu.View.Check.min.js", 4 | "lineCount":2, 5 | "mappings":"AAEA,IAAIA,MAAQC,MAAAD,MAARA,EAAwB,EAC5BA,MAAAE,KAAA,CAAaD,MAAAD,MAAAE,KAAb,EAAkC,EAClCF,MAAAE,KAAAC,MAAA,CAAmBC,QAAQ,EAAG,CAC1B,IAAIC,EAAQ,IAEZA,EAAAC,KAAA,CAAaC,QAAQ,EAAG,CACpBF,CAAAG,YAAA,EACAH,EAAAI,WAAA,EAFoB,CAKxBJ,EAAAG,YAAA,CAAoBE,QAAQ,EAAG,CAC3BC,CAAA,CAAE,YAAF,CAAAC,QAAA,CAAwB,CACpBC,aAAc,UADM,CAEpBC,WAAY,YAFQ,CAGpBC,aAAcA,QAAQ,CAACC,CAAD,CAAU,CAC5B,MAAOA,EAAAC,SAAAC,QAAA,CAAyB,OAAzB,CADqB,CAHZ,CAAxB,CAD2B,CAU/Bb,EAAAI,WAAA,CAAmBU,QAAQ,EAAG,CAC1BR,CAAA,CAAE,YAAF,CAAAS,MAAA,CAAsB,QAAQ,EAAG,CACRT,CAAA,CAAE,YAAF,CAAAC,QAAA,EAAAS,SAAAC,EACrB,EACIC,UAAAC,QAAA,EAHyB,CAAjC,CAD0B,CAS9B,OAAO,CACHlB,KAAMA,QAAQ,EAAG,CACbD,CAAAC,KAAA,EADa,CADd,CA3BmB,CAkC9BmB;QAASA,oBAAmB,EAAG,CAC3Bd,CAAA,CAAE,YAAF,CAAAe,OAAA,EAD2B;", 6 | "sources":["/js/Horyu.View.Check.js"], 7 | "names":["Horyu","window","View","Check","Horyu.View.Check","_this","init","_this.init","initParsley","bindEvents","_this.initParsley","$","parsley","successClass","errorClass","classHandler","element","$element","closest","_this.bindEvents","click","validate","isFormValidate","grecaptcha","execute","onReCaptchaCallback","submit"] 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/form/PrizeSaveForm.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.form; 2 | 3 | import javax.validation.constraints.NotNull; 4 | 5 | /** 6 | * Created by horyu on 2018-04-14 7 | */ 8 | public class PrizeSaveForm { 9 | @NotNull 10 | private int prizeId; 11 | 12 | @NotNull 13 | private int companyId; 14 | 15 | @NotNull 16 | private String prizeName; 17 | 18 | @NotNull 19 | private int prizeAmount; 20 | 21 | public int getPrizeId() { 22 | return prizeId; 23 | } 24 | 25 | public void setPrizeId(int prizeId) { 26 | this.prizeId = prizeId; 27 | } 28 | 29 | public int getCompanyId() { 30 | return companyId; 31 | } 32 | 33 | public void setCompanyId(int companyId) { 34 | this.companyId = companyId; 35 | } 36 | 37 | public String getPrizeName() { 38 | return prizeName; 39 | } 40 | 41 | public void setPrizeName(String prizeName) { 42 | this.prizeName = prizeName; 43 | } 44 | 45 | public int getPrizeAmount() { 46 | return prizeAmount; 47 | } 48 | 49 | public void setPrizeAmount(int prizeAmount) { 50 | this.prizeAmount = prizeAmount; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/Prize.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | /** 4 | * Created by horyu on 2018-04-14 5 | */ 6 | public class Prize { 7 | private int eventId; 8 | private int prizeId; 9 | private int companyId; 10 | private String prizeName; 11 | private int prizeAmount; 12 | 13 | public int getEventId() { 14 | return eventId; 15 | } 16 | 17 | public void setEventId(int eventId) { 18 | this.eventId = eventId; 19 | } 20 | 21 | public int getPrizeId() { 22 | return prizeId; 23 | } 24 | 25 | public void setPrizeId(int prizeId) { 26 | this.prizeId = prizeId; 27 | } 28 | 29 | public int getCompanyId() { 30 | return companyId; 31 | } 32 | 33 | public void setCompanyId(int companyId) { 34 | this.companyId = companyId; 35 | } 36 | 37 | public String getPrizeName() { 38 | return prizeName; 39 | } 40 | 41 | public void setPrizeName(String prizeName) { 42 | this.prizeName = prizeName; 43 | } 44 | 45 | public int getPrizeAmount() { 46 | return prizeAmount; 47 | } 48 | 49 | public void setPrizeAmount(int prizeAmount) { 50 | this.prizeAmount = prizeAmount; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/config/WebMVCConfig.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.config; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.interceptor.AuthenticationInterceptor; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | @Configuration 11 | public class WebMVCConfig implements WebMvcConfigurer { 12 | private AuthenticationInterceptor authenticationInterceptor; 13 | 14 | @Autowired 15 | public void setAuthenticationInterceptor(AuthenticationInterceptor authenticationInterceptor) { 16 | this.authenticationInterceptor = authenticationInterceptor; 17 | } 18 | 19 | @Override 20 | public void addInterceptors(InterceptorRegistry registry) { 21 | registry.addInterceptor(authenticationInterceptor) 22 | .addPathPatterns("/admin/**") 23 | .excludePathPatterns(View.ADMIN_LOGIN.toPath()) 24 | .excludePathPatterns("/admin/register/**") 25 | .excludePathPatterns("/admin/logout"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/static/css/style.css: -------------------------------------------------------------------------------- 1 | #main-container { 2 | margin-top: 20px; 3 | margin-bottom: 100px; 4 | } 5 | 6 | .hidden-input { 7 | visibility: hidden; 8 | } 9 | 10 | .invalid-feedback { 11 | font-size: 13pt !important; 12 | } 13 | 14 | .company-gift-table { 15 | min-width: 800px; 16 | } 17 | 18 | .company-gift-table td { 19 | vertical-align: middle; 20 | } 21 | 22 | .company-gift-table .company-cell { 23 | min-width: 300px; 24 | } 25 | 26 | .company-gift-table .gift-cell { 27 | min-width: 200px 28 | } 29 | 30 | .company-gift-table .event-winner-pending-cell { 31 | color: #9e9e9e !important; 32 | } 33 | 34 | .company-gift-table .event-winner-cell { 35 | color: #0043ff !important; 36 | font-weight: bold; 37 | } 38 | 39 | #copyright { 40 | text-align: center; 41 | width: 100%; 42 | position: fixed; 43 | bottom: 0; 44 | margin-bottom: 0; 45 | font-weight: bold; 46 | padding-bottom: 2px; 47 | padding-top: 2px; 48 | z-index: 1000; 49 | } 50 | 51 | .table-responsive { 52 | border-left: 1px solid #dddddd !important; 53 | border-right: 1px solid #dddddd !important; 54 | border-bottom: 1px solid #dddddd !important; 55 | } 56 | 57 | .company-logo { 58 | max-width: 150px; 59 | height: auto; 60 | } -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/mapper/EventMapper.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.mapper; 2 | 3 | import com.horyu1234.eventangel.constant.EventStatus; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.factory.DateFactory; 6 | import org.springframework.jdbc.core.RowMapper; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.sql.ResultSet; 10 | import java.sql.SQLException; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | * Created by horyu on 2018-06-17. 15 | */ 16 | @Component 17 | public class EventMapper implements RowMapper { 18 | @Override 19 | public Event mapRow(ResultSet rs, int rowNum) throws SQLException { 20 | Event event = new Event(); 21 | event.setEventId(rs.getInt("EVENT_ID")); 22 | event.setEventTitle(rs.getString("EVENT_TITLE")); 23 | event.setEventDetail(rs.getString("EVENT_DETAIL")); 24 | event.setEventStatus(EventStatus.valueOf(rs.getString("EVENT_STATUS"))); 25 | 26 | event.setEventStartTime(LocalDateTime.parse(rs.getString("EVENT_START_TIME"), DateFactory.DATABASE_FORMAT)); 27 | event.setEventEndTime(LocalDateTime.parse(rs.getString("EVENT_END_TIME"), DateFactory.DATABASE_FORMAT)); 28 | 29 | return event; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/resources/static/css/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'NanumBarunGothic'; 3 | font-style: normal; 4 | font-weight: 400; 5 | src: url('../webfonts/NanumBarunGothicWeb.eot'); 6 | src: url('../webfonts/NanumBarunGothicWeb.eot?#iefix') format('embedded-opentype'), url('../webfonts/NanumBarunGothicWeb.woff') format('woff'), url('../webfonts/NanumBarunGothicWeb.ttf') format('truetype'); 7 | } 8 | 9 | @font-face { 10 | font-family: 'NanumBarunGothic'; 11 | font-style: normal; 12 | font-weight: 700; 13 | src: url('../webfonts/NanumBarunGothicWebBold.eot'); 14 | src: url('../webfonts/NanumBarunGothicWebBold.eot?#iefix') format('embedded-opentype'), url('../webfonts/NanumBarunGothicWebBold.woff') format('woff'), url('../webfonts/NanumBarunGothicWebBold.ttf') format('truetype') 15 | } 16 | 17 | @font-face { 18 | font-family: 'NanumBarunGothic'; 19 | font-style: normal; 20 | font-weight: 300; 21 | src: url('../webfonts/NanumBarunGothicWebLight.eot'); 22 | src: url('../webfonts/NanumBarunGothicWebLight.eot?#iefix') format('embedded-opentype'), url('../webfonts/NanumBarunGothicWebLight.woff') format('woff'), url('../webfonts/NanumBarunGothicWebLight.ttf') format('truetype'); 23 | } 24 | 25 | html, body, h1, h2, h3, h4, h5, h6, li, p, a, div, option, label, span { 26 | font-family: 'NanumBarunGothic', sans-serif !important; 27 | } -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/AccountService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.horyu1234.eventangel.database.dao.AccountDAO; 4 | import com.horyu1234.eventangel.domain.Account; 5 | import org.mindrot.jbcrypt.BCrypt; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import javax.annotation.PostConstruct; 10 | import java.util.List; 11 | 12 | /** 13 | * Created by horyu on 2018-04-04 14 | */ 15 | @Service 16 | public class AccountService { 17 | private AccountDAO accountDAO; 18 | 19 | @PostConstruct 20 | public void init() { 21 | accountDAO.createTableIfNotExist(); 22 | } 23 | 24 | @Autowired 25 | public void setAccountDAO(AccountDAO accountDAO) { 26 | this.accountDAO = accountDAO; 27 | } 28 | 29 | public Account login(String username, String password) { 30 | List storedAccounts = accountDAO.getAccount(username); 31 | if (storedAccounts.isEmpty()) { 32 | return null; 33 | } 34 | 35 | Account storedAccount = storedAccounts.get(0); 36 | String combindedPassword = username + "/" + password; 37 | 38 | if (BCrypt.checkpw(combindedPassword, storedAccount.getPassword())) { 39 | return storedAccount; 40 | } 41 | 42 | return null; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/CustomErrorController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 5 | import org.springframework.boot.web.servlet.error.ErrorController; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | 11 | import javax.servlet.RequestDispatcher; 12 | import javax.servlet.http.HttpServletRequest; 13 | 14 | /** 15 | * Created by horyu on 2018-04-16 16 | */ 17 | @Controller 18 | public class CustomErrorController implements ErrorController { 19 | @RequestMapping("/error") 20 | public String handleError(Model model, HttpServletRequest request) { 21 | int statusCode = (int) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); 22 | 23 | if (statusCode == HttpStatus.NOT_FOUND.value()) { 24 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ERROR_404.toView()); 25 | } else { 26 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ERROR_500.toView()); 27 | } 28 | 29 | return View.LAYOUT.getTemplateName(); 30 | } 31 | 32 | @Override 33 | public String getErrorPath() { 34 | return "/error"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/Company.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | /** 4 | * Created by horyu on 2018-04-06 5 | */ 6 | public class Company { 7 | private int eventId; 8 | private int companyId; 9 | private String companyName; 10 | private String companyDetail; 11 | private String companyLogoImageFileName; 12 | 13 | public int getEventId() { 14 | return eventId; 15 | } 16 | 17 | public void setEventId(int eventId) { 18 | this.eventId = eventId; 19 | } 20 | 21 | public int getCompanyId() { 22 | return companyId; 23 | } 24 | 25 | public void setCompanyId(int companyId) { 26 | this.companyId = companyId; 27 | } 28 | 29 | public String getCompanyName() { 30 | return companyName; 31 | } 32 | 33 | public void setCompanyName(String companyName) { 34 | this.companyName = companyName; 35 | } 36 | 37 | public String getCompanyDetail() { 38 | return companyDetail; 39 | } 40 | 41 | public void setCompanyDetail(String companyDetail) { 42 | this.companyDetail = companyDetail; 43 | } 44 | 45 | public String getCompanyLogoImageFileName() { 46 | return companyLogoImageFileName; 47 | } 48 | 49 | public void setCompanyLogoImageFileName(String companyLogoImageFileName) { 50 | this.companyLogoImageFileName = companyLogoImageFileName; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/rest/PrizeSettingRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin.rest; 2 | 3 | import com.horyu1234.eventangel.domain.Event; 4 | import com.horyu1234.eventangel.service.EventService; 5 | import com.horyu1234.eventangel.service.PrizeService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * Created by horyu on 2018-04-04 13 | */ 14 | @RequestMapping("/admin/prizeSetting") 15 | @RestController 16 | public class PrizeSettingRestController { 17 | private EventService eventService; 18 | private PrizeService prizeService; 19 | 20 | @Autowired 21 | public void setEventService(EventService eventService) { 22 | this.eventService = eventService; 23 | } 24 | 25 | @Autowired 26 | public void setPrizeService(PrizeService prizeService) { 27 | this.prizeService = prizeService; 28 | } 29 | 30 | @RequestMapping(value = "/deletePrize", method = RequestMethod.POST) 31 | public String deletePrize(int prizeId) { 32 | Event currentEvent = eventService.getCurrentEvent(); 33 | 34 | prizeService.deletePrize(currentEvent.getEventId(), prizeId); 35 | 36 | return "success"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/rest/DuplicatedRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin.rest; 2 | 3 | import com.horyu1234.eventangel.domain.DuplicatedApplicant; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.service.ApplicantService; 6 | import com.horyu1234.eventangel.service.EventService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.util.List; 13 | 14 | @RequestMapping("/admin/duplicated") 15 | @RestController 16 | public class DuplicatedRestController { 17 | private EventService eventService; 18 | private ApplicantService applicantService; 19 | 20 | @Autowired 21 | public DuplicatedRestController(EventService eventService, ApplicantService applicantService) { 22 | this.eventService = eventService; 23 | this.applicantService = applicantService; 24 | } 25 | 26 | @RequestMapping(value = "/getDuplicated", method = RequestMethod.POST) 27 | public List getDuplicated(String columnName) { 28 | Event currentEvent = eventService.getCurrentEvent(); 29 | 30 | return applicantService.getDuplicatedApplicant(currentEvent.getEventId(), columnName); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/mapper/ApplicantMapper.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.mapper; 2 | 3 | import com.horyu1234.eventangel.domain.Applicant; 4 | import com.horyu1234.eventangel.factory.DateFactory; 5 | import org.springframework.jdbc.core.RowMapper; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.sql.ResultSet; 9 | import java.sql.SQLException; 10 | import java.time.LocalDateTime; 11 | 12 | @Component 13 | public class ApplicantMapper implements RowMapper { 14 | @Override 15 | public Applicant mapRow(ResultSet rs, int rowNum) throws SQLException { 16 | Applicant applicant = new Applicant(); 17 | applicant.setEventId(rs.getInt("EVENT_ID")); 18 | applicant.setApplyEmail(rs.getString("APPLY_EMAIL")); 19 | applicant.setYoutubeNickname(rs.getString("YOUTUBE_NICKNAME")); 20 | applicant.setApplyTime(LocalDateTime.parse(rs.getString("APPLY_TIME"), DateFactory.DATABASE_FORMAT)); 21 | applicant.setIpAddress(rs.getString("IP_ADDRESS")); 22 | applicant.setReferer(rs.getString("REFERER")); 23 | applicant.setUserAgent(rs.getString("USER_AGENT")); 24 | applicant.setFingerprint2(rs.getString("FINGERPRINT2")); 25 | applicant.setDuplicated("Y".equals(rs.getString("DUPLICATED_YN"))); 26 | applicant.setDupCheckAdminName(rs.getString("DUP_CHECK_ADMIN_NAME")); 27 | 28 | return applicant; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/EventWinnerDetail.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | /** 6 | * Created by horyu on 2018-04-16 7 | */ 8 | public class EventWinnerDetail { 9 | private int eventId; 10 | private int prizeId; 11 | private Applicant applicant; 12 | private LocalDateTime winTime; 13 | 14 | public static EventWinnerDetail fromEventWinner(EventWinner eventWinner) { 15 | EventWinnerDetail eventWinnerDetail = new EventWinnerDetail(); 16 | eventWinnerDetail.setEventId(eventWinner.getEventId()); 17 | eventWinnerDetail.setPrizeId(eventWinner.getPrizeId()); 18 | eventWinnerDetail.setWinTime(eventWinner.getWinTime()); 19 | 20 | return eventWinnerDetail; 21 | } 22 | 23 | public int getEventId() { 24 | return eventId; 25 | } 26 | 27 | public void setEventId(int eventId) { 28 | this.eventId = eventId; 29 | } 30 | 31 | public int getPrizeId() { 32 | return prizeId; 33 | } 34 | 35 | public void setPrizeId(int prizeId) { 36 | this.prizeId = prizeId; 37 | } 38 | 39 | public Applicant getApplicant() { 40 | return applicant; 41 | } 42 | 43 | public void setApplicant(Applicant applicant) { 44 | this.applicant = applicant; 45 | } 46 | 47 | public LocalDateTime getWinTime() { 48 | return winTime; 49 | } 50 | 51 | public void setWinTime(LocalDateTime winTime) { 52 | this.winTime = winTime; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/parsley-2.8.1/i18n/en.js: -------------------------------------------------------------------------------- 1 | // This is included with the Parsley library itself, 2 | // thus there is no use in adding it to your project. 3 | 4 | 5 | Parsley.addMessages('en', { 6 | defaultMessage: "This value seems to be invalid.", 7 | type: { 8 | email: "This value should be a valid email.", 9 | url: "This value should be a valid url.", 10 | number: "This value should be a valid number.", 11 | integer: "This value should be a valid integer.", 12 | digits: "This value should be digits.", 13 | alphanum: "This value should be alphanumeric." 14 | }, 15 | notblank: "This value should not be blank.", 16 | required: "This value is required.", 17 | pattern: "This value seems to be invalid.", 18 | min: "This value should be greater than or equal to %s.", 19 | max: "This value should be lower than or equal to %s.", 20 | range: "This value should be between %s and %s.", 21 | minlength: "This value is too short. It should have %s characters or more.", 22 | maxlength: "This value is too long. It should have %s characters or fewer.", 23 | length: "This value length is invalid. It should be between %s and %s characters long.", 24 | mincheck: "You must select at least %s choices.", 25 | maxcheck: "You must select %s choices or fewer.", 26 | check: "You must select between %s and %s choices.", 27 | equalto: "This value should be the same." 28 | }); 29 | 30 | Parsley.setLocale('en'); 31 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/check/check.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 |
6 | 이벤트 응모 여부를 확인하실 수 있습니다. 7 |
8 |
9 |
10 | 11 | 16 |
17 |
18 | 19 |
20 |
26 |
27 | 28 | 29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/dao/AccountDAO.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.dao; 2 | 3 | import com.horyu1234.eventangel.domain.Account; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.jdbc.core.BeanPropertyRowMapper; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by horyu on 2018-04-15 13 | */ 14 | @Repository 15 | public class AccountDAO { 16 | private JdbcTemplate jdbcTemplate; 17 | 18 | @Autowired 19 | public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 20 | this.jdbcTemplate = jdbcTemplate; 21 | } 22 | 23 | public void createTableIfNotExist() { 24 | jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `ACCOUNT` ( " + 25 | "`USERNAME` VARCHAR(20) NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 26 | "`PASSWORD` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 27 | "`NICKNAME` VARCHAR(20) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', " + 28 | "PRIMARY KEY (`USERNAME`) " + 29 | ") " + 30 | "COLLATE='utf8mb4_unicode_ci' " + 31 | "ENGINE=InnoDB;"); 32 | } 33 | 34 | public List getAccount(String username) { 35 | return jdbcTemplate.query( 36 | "SELECT * FROM `ACCOUNT` " + 37 | "WHERE USERNAME = ? " + 38 | "LIMIT 1;", 39 | new Object[]{username}, 40 | new BeanPropertyRowMapper<>(Account.class)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/filter/MinifyFilter.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.filter; 2 | 3 | import com.googlecode.htmlcompressor.compressor.HtmlCompressor; 4 | import com.googlecode.htmlcompressor.compressor.YuiCssCompressor; 5 | import com.googlecode.htmlcompressor.compressor.YuiJavaScriptCompressor; 6 | import com.horyu1234.eventangel.CharResponseWrapper; 7 | 8 | import javax.servlet.*; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | 12 | /** 13 | * Created by horyu on 2018-01-15 14 | */ 15 | public class MinifyFilter implements Filter { 16 | private HtmlCompressor htmlCompressor; 17 | 18 | @Override 19 | public void init(FilterConfig filterConfig) { 20 | htmlCompressor = new HtmlCompressor(); 21 | 22 | htmlCompressor.setCssCompressor(new YuiCssCompressor()); 23 | htmlCompressor.setJavaScriptCompressor(new YuiJavaScriptCompressor()); 24 | 25 | htmlCompressor.setCompressCss(true); 26 | htmlCompressor.setCompressJavaScript(true); 27 | } 28 | 29 | @Override 30 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 31 | CharResponseWrapper responseWrapper = new CharResponseWrapper( 32 | (HttpServletResponse) response); 33 | 34 | chain.doFilter(request, responseWrapper); 35 | 36 | String servletResponse = responseWrapper.toString(); 37 | if (!response.isCommitted()) { 38 | response.getWriter().write(htmlCompressor.compress(servletResponse)); 39 | } 40 | } 41 | 42 | @Override 43 | public void destroy() { 44 | // nothing 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventHistory.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.EventHistory=function(e){var b=this;b.options=$.extend({eventList:[],applicantCountMap:{}},e);b.init=function(){b.changeMainContainerWidth();b.updateTable();b.bindEvents()};b.changeMainContainerWidth=function(){var a=$("#main-container");a.removeClass("container");a.addClass("container-full")};b.updateTable=function(){var a=$(".event-history-table").find("tbody");a.empty();b.options.eventList.forEach(function(c){var d=$("\x3ctr\x3e\x3c/tr\x3e");d.append($("\x3ctd\x3e").text(c.eventId)); 3 | d.append($("\x3ctd\x3e").text(c.eventTitle));d.append($("\x3ctd\x3e").text(c.eventDetail));d.append($("\x3ctd\x3e").text(b.getEventStatusText(c.eventStatus)));d.append($("\x3ctd\x3e").html(moment(c.eventStartTime).format("YYYY\ub144 MMMM D\uc77c dddd\x3cbr/\x3eA h\uc2dc mm\ubd84 ss\ucd08")));d.append($("\x3ctd\x3e").html(moment(c.eventEndTime).format("YYYY\ub144 MMMM D\uc77c dddd\x3cbr/\x3eA h\uc2dc mm\ubd84 ss\ucd08")));var e=b.options.applicantCountMap[c.eventId];5/keystore.p12 10 | key-store-password: 11 | keyStoreType: PKCS12 12 | keyAlias: tomcat 13 | google: 14 | recaptcha: 15 | secret: 16 | spring: 17 | profiles: 18 | active: production 19 | naver: 20 | realtime-search: 21 | referer: none 22 | key: none 23 | 24 | --- 25 | spring: 26 | profiles: dev 27 | servlet: 28 | multipart: 29 | max-file-size: 5MB 30 | session: 31 | store-type: jdbc 32 | jdbc: 33 | initialize-schema: always 34 | thymeleaf: 35 | cache: false 36 | datasource: 37 | driver-class-name: com.mysql.jdbc.Driver 38 | url: jdbc:mysql://:/ 39 | username: 40 | password: 41 | validation-query: SELECT 1 42 | test-while-idle: true 43 | max-active: 200 44 | max-idle: 100 45 | min-idle: 20 46 | max-wait: 1000 47 | upload-dir: 48 | company-logo-image: 49 | 50 | --- 51 | spring: 52 | profiles: production 53 | servlet: 54 | multipart: 55 | max-file-size: 5MB 56 | session: 57 | store-type: jdbc 58 | jdbc: 59 | initialize-schema: always 60 | thymeleaf: 61 | cache: true 62 | datasource: 63 | driver-class-name: com.mysql.jdbc.Driver 64 | url: jdbc:mysql://:/ 65 | username: 66 | password: 67 | validation-query: SELECT 1 68 | test-while-idle: true 69 | max-active: 200 70 | max-idle: 100 71 | min-idle: 20 72 | max-wait: 1000 73 | upload-dir: 74 | company-logo-image: -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/form/EventSettingForm.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.form; 2 | 3 | import com.horyu1234.eventangel.constant.EventStatus; 4 | 5 | import javax.validation.constraints.NotNull; 6 | 7 | /** 8 | * Created by horyu on 2018-04-06 9 | */ 10 | public class EventSettingForm { 11 | @NotNull 12 | private int eventId; 13 | 14 | @NotNull 15 | private String eventTitle; 16 | 17 | @NotNull 18 | private String eventDetail; 19 | 20 | @NotNull 21 | private EventStatus eventStatus; 22 | 23 | @NotNull 24 | private long eventStartTime; 25 | 26 | @NotNull 27 | private long eventEndTime; 28 | 29 | public int getEventId() { 30 | return eventId; 31 | } 32 | 33 | public void setEventId(int eventId) { 34 | this.eventId = eventId; 35 | } 36 | 37 | public EventStatus getEventStatus() { 38 | return eventStatus; 39 | } 40 | 41 | public void setEventStatus(EventStatus eventStatus) { 42 | this.eventStatus = eventStatus; 43 | } 44 | 45 | public long getEventStartTime() { 46 | return eventStartTime; 47 | } 48 | 49 | public void setEventStartTime(long eventStartTime) { 50 | this.eventStartTime = eventStartTime; 51 | } 52 | 53 | public long getEventEndTime() { 54 | return eventEndTime; 55 | } 56 | 57 | public void setEventEndTime(long eventEndTime) { 58 | this.eventEndTime = eventEndTime; 59 | } 60 | 61 | public String getEventTitle() { 62 | return eventTitle; 63 | } 64 | 65 | public void setEventTitle(String eventTitle) { 66 | this.eventTitle = eventTitle; 67 | } 68 | 69 | public String getEventDetail() { 70 | return eventDetail; 71 | } 72 | 73 | public void setEventDetail(String eventDetail) { 74 | this.eventDetail = eventDetail; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/constant/View.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.constant; 2 | 3 | /** 4 | * Created by horyu on 2018-04-07 5 | */ 6 | public enum View { 7 | LAYOUT("layout"), 8 | ADMIN_LOGIN("admin/login"), 9 | ADMIN_EVENT_SETTING("admin/eventSetting"), 10 | ADMIN_COMPANY_SETTING("admin/companySetting"), 11 | ADMIN_APPLICANT_LIST("admin/applicantList"), 12 | ADMIN_DUPLICATED("admin/duplicated"), 13 | ADMIN_DUPLICATED_VIEW("admin/duplicatedView"), 14 | ADMIN_EVENT_HISTORY("admin/eventHistory"), 15 | ADMIN_EVENT_HISTORY_VIEW("admin/eventHistoryView"), 16 | ADMIN_LOTTERY("admin/lottery"), 17 | ADMIN_PRIZE_SETTING("admin/prizeSetting"), 18 | ADMIN_REGISTER("admin/register"), 19 | APPLY("apply"), 20 | APPLY_APPLY("apply/apply"), 21 | APPLY_WRONG_WAY("apply/wrongWay"), 22 | APPLY_REDUPLICATION("apply/reduplication"), 23 | APPLY_ALREADY_END("apply/alreadyEnd"), 24 | APPLY_INVALID_FORM("apply/invalidForm"), 25 | APPLY_FAIL_RECAPTCHA("apply/failReCaptcha"), 26 | APPLY_SUCCESS("apply/success"), 27 | CHECK_CHECK("check/check"), 28 | CHECK_NOT_OPEN_EVENT("check/notOpenEvent"), 29 | CHECK_EXIST_APPLY("check/existApply"), 30 | CHECK_NOT_EXIST_APPLY("check/notExistApply"), 31 | PRIVACY("privacy"), 32 | FAIL_RECAPTCHA("failReCaptcha"), 33 | ERROR_404("error/404"), 34 | ERROR_500("error/500"); 35 | 36 | private String viewName; 37 | 38 | View(String viewName) { 39 | this.viewName = viewName; 40 | } 41 | 42 | public String getTemplateName() { 43 | return viewName; 44 | } 45 | 46 | public String toPath() { 47 | return "/" + viewName; 48 | } 49 | 50 | public String toRedirect() { 51 | return "redirect:/" + viewName + "/"; 52 | } 53 | 54 | public String toView() { 55 | return "view/" + viewName; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/rest/CompanySettingRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin.rest; 2 | 3 | import com.horyu1234.eventangel.domain.Event; 4 | import com.horyu1234.eventangel.service.CompanyService; 5 | import com.horyu1234.eventangel.service.EventService; 6 | import com.horyu1234.eventangel.service.PrizeService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | /** 13 | * Created by horyu on 2018-04-04 14 | */ 15 | @RequestMapping("/admin/companySetting") 16 | @RestController 17 | public class CompanySettingRestController { 18 | private EventService eventService; 19 | private CompanyService companyService; 20 | private PrizeService prizeService; 21 | 22 | @Autowired 23 | public void setEventService(EventService eventService) { 24 | this.eventService = eventService; 25 | } 26 | 27 | @Autowired 28 | public void setCompanyService(CompanyService companyService) { 29 | this.companyService = companyService; 30 | } 31 | 32 | @Autowired 33 | public void setPrizeService(PrizeService prizeService) { 34 | this.prizeService = prizeService; 35 | } 36 | 37 | @RequestMapping(value = "/deleteCompany", method = RequestMethod.POST) 38 | public String deleteCompany(int companyId) { 39 | Event currentEvent = eventService.getCurrentEvent(); 40 | 41 | prizeService.deletePrizeByCompanyId(currentEvent.getEventId(), companyId); 42 | 43 | companyService.deleteCompanyLogoImage(currentEvent.getEventId(), companyId); 44 | companyService.deleteCompany(currentEvent.getEventId(), companyId); 45 | 46 | return "success"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/config/HttpSecureConfig.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.config; 2 | 3 | import org.apache.catalina.Context; 4 | import org.apache.catalina.connector.Connector; 5 | import org.apache.tomcat.util.descriptor.web.SecurityCollection; 6 | import org.apache.tomcat.util.descriptor.web.SecurityConstraint; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; 9 | import org.springframework.context.annotation.Bean; 10 | 11 | //@Configuration 12 | public class HttpSecureConfig { 13 | @Value("${server.port}") 14 | private int httpSecurePort; 15 | 16 | @Value("${server.http-port}") 17 | private int httpPort; 18 | 19 | @Bean 20 | public TomcatServletWebServerFactory servletContainer() { 21 | TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() { 22 | @Override 23 | protected void postProcessContext(Context context) { 24 | SecurityConstraint securityConstraint = new SecurityConstraint(); 25 | securityConstraint.setUserConstraint("CONFIDENTIAL"); 26 | 27 | SecurityCollection collection = new SecurityCollection(); 28 | collection.addPattern("/*"); 29 | 30 | securityConstraint.addCollection(collection); 31 | context.addConstraint(securityConstraint); 32 | } 33 | }; 34 | tomcat.addAdditionalTomcatConnectors(redirectConnector()); 35 | return tomcat; 36 | } 37 | 38 | private Connector redirectConnector() { 39 | Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); 40 | connector.setScheme("http"); 41 | connector.setPort(httpPort); 42 | connector.setSecure(false); 43 | connector.setRedirectPort(httpSecurePort); 44 | 45 | return connector; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/admin/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 |
6 | 본 로그인은 관리자 전용입니다. 7 |
8 |
9 | 10 | 아이디 또는 비밀번호가 맞지 않습니다. 11 |
12 | 13 |
15 |
16 | 17 | 20 |
21 | 22 |
23 | 24 | 27 |
28 | 29 |
30 |
36 |
37 | 38 | 39 |
40 |
41 |
42 | 43 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/rest/EventSettingRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin.rest; 2 | 3 | import com.horyu1234.eventangel.constant.EventStatus; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.service.ApplicantService; 6 | import com.horyu1234.eventangel.service.EventService; 7 | import com.horyu1234.eventangel.service.EventWinnerService; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | /** 14 | * Created by horyu on 2018-04-16 15 | */ 16 | @RequestMapping("/admin/eventSetting") 17 | @RestController 18 | public class EventSettingRestController { 19 | private EventService eventService; 20 | private ApplicantService applicantService; 21 | private EventWinnerService eventWinnerService; 22 | 23 | @Autowired 24 | public void setEventService(EventService eventService) { 25 | this.eventService = eventService; 26 | } 27 | 28 | @Autowired 29 | public void setApplicantService(ApplicantService applicantService) { 30 | this.applicantService = applicantService; 31 | } 32 | 33 | @Autowired 34 | public void setEventWinnerService(EventWinnerService eventWinnerService) { 35 | this.eventWinnerService = eventWinnerService; 36 | } 37 | 38 | @RequestMapping(value = "/endEvent", method = RequestMethod.GET) 39 | public String endEvent() { 40 | eventService.newEvent(); 41 | 42 | return "success"; 43 | } 44 | 45 | @RequestMapping(value = "/resetEventWinner", method = RequestMethod.GET) 46 | public String resetEventWinner() { 47 | Event currentEvent = eventService.getCurrentEvent(); 48 | currentEvent.setEventStatus(EventStatus.CLOSE); 49 | 50 | eventWinnerService.resetEventWinner(currentEvent.getEventId()); 51 | eventService.updateEvent(currentEvent); 52 | 53 | return "success"; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/LotteryService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.horyu1234.eventangel.constant.EventStatus; 4 | import com.horyu1234.eventangel.domain.Applicant; 5 | import com.horyu1234.eventangel.domain.Event; 6 | import org.apache.commons.math3.random.MersenneTwister; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | 13 | /** 14 | * Created by horyu on 2018-04-16 15 | */ 16 | @Service 17 | public class LotteryService { 18 | private EventService eventService; 19 | private ApplicantService applicantService; 20 | private EventWinnerService eventWinnerService; 21 | 22 | @Autowired 23 | public void setEventService(EventService eventService) { 24 | this.eventService = eventService; 25 | } 26 | 27 | @Autowired 28 | public void setApplicantService(ApplicantService applicantService) { 29 | this.applicantService = applicantService; 30 | } 31 | 32 | @Autowired 33 | public void setEventWinnerService(EventWinnerService eventWinnerService) { 34 | this.eventWinnerService = eventWinnerService; 35 | } 36 | 37 | public Applicant lottery(int prizeId) { 38 | Event currentEvent = eventService.getCurrentEvent(); 39 | 40 | if (currentEvent.getEventStatus() != EventStatus.LOTTERY) { 41 | currentEvent.setEventStatus(EventStatus.LOTTERY); 42 | eventService.updateEvent(currentEvent); 43 | } 44 | 45 | List applicantList = applicantService.getApplicantList(currentEvent.getEventId()); 46 | applicantList = applicantList.stream().filter(applicant -> !applicant.isDuplicated()).collect(Collectors.toList()); 47 | 48 | MersenneTwister mersenneTwister = new MersenneTwister(); 49 | int randomIndex = mersenneTwister.nextInt(applicantList.size()); 50 | 51 | Applicant lotteryedApplicant = applicantList.get(randomIndex); 52 | 53 | int eventId = currentEvent.getEventId(); 54 | eventWinnerService.addEventWinner(eventId, prizeId, lotteryedApplicant.getApplyEmail()); 55 | 56 | return lotteryedApplicant; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/dao/EventWinnerDAO.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.dao; 2 | 3 | import com.horyu1234.eventangel.database.mapper.EventWinnerMapper; 4 | import com.horyu1234.eventangel.domain.EventWinner; 5 | import com.horyu1234.eventangel.factory.DateFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.stereotype.Repository; 9 | 10 | import java.time.LocalDateTime; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by horyu on 2018-04-15 15 | */ 16 | @Repository 17 | public class EventWinnerDAO { 18 | private JdbcTemplate jdbcTemplate; 19 | private EventWinnerMapper eventWinnerMapper; 20 | 21 | @Autowired 22 | public EventWinnerDAO(JdbcTemplate jdbcTemplate, EventWinnerMapper eventWinnerMapper) { 23 | this.jdbcTemplate = jdbcTemplate; 24 | this.eventWinnerMapper = eventWinnerMapper; 25 | } 26 | 27 | public void createTableIfNotExist() { 28 | jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `EVENT_WINNER` ( " + 29 | "`EVENT_ID` INT(11) NOT NULL, " + 30 | "`PRIZE_ID` INT(11) NOT NULL, " + 31 | "`APPLY_EMAIL` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 32 | "`WIN_TIME` DATETIME NOT NULL, " + 33 | "PRIMARY KEY (`EVENT_ID`, `PRIZE_ID`, `APPLY_EMAIL`) " + 34 | ") " + 35 | "COLLATE='utf8mb4_unicode_ci' " + 36 | "ENGINE=InnoDB;"); 37 | } 38 | 39 | public List getWinnerList(int eventId) { 40 | return jdbcTemplate.query( 41 | "SELECT * FROM `EVENT_WINNER` " + 42 | "WHERE EVENT_ID = ?;", 43 | new Object[]{eventId}, 44 | eventWinnerMapper); 45 | } 46 | 47 | public void insertEventWinner(int eventId, int prizeId, String applyEmail, LocalDateTime winTime) { 48 | jdbcTemplate.update("INSERT INTO `EVENT_WINNER` (EVENT_ID, PRIZE_ID, APPLY_EMAIL, WIN_TIME) VALUES (?, ?, ?, ?);", 49 | eventId, prizeId, applyEmail, DateFactory.DATABASE_FORMAT.format(winTime)); 50 | } 51 | 52 | public void resetEventWinner(int eventId) { 53 | jdbcTemplate.update("DELETE FROM `EVENT_WINNER` " + 54 | "WHERE EVENT_ID = ?;", 55 | eventId); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/ReCaptchaService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018. horyu1234(류현오) All rights reserved 3 | * 4 | * 본 프로젝트의 소스는 이용자 본인의 학습 용도로만 사용하는 것을 허용하며, 영리추구, 운영 등등 원 저작자의 허락을 받지 않은 행위는 저작권법에 의거하여 엄격히 금지합니다 5 | * 6 | * 라이선스에 대한 세부 정보를 얻으시려면 아래를 방문해주시기 바랍니다. 7 | * https://github.com/horyu1234/EventAngel/blob/master/LICENSE.md 8 | */ 9 | 10 | package com.horyu1234.eventangel.service; 11 | 12 | import com.horyu1234.eventangel.controller.ApplyController; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.beans.factory.annotation.Value; 17 | import org.springframework.boot.web.client.RestTemplateBuilder; 18 | import org.springframework.http.ResponseEntity; 19 | import org.springframework.stereotype.Service; 20 | 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | @Service 25 | public class ReCaptchaService { 26 | private static final Logger LOGGER = LoggerFactory.getLogger(ReCaptchaService.class); 27 | private static final String GOOGLE_RECAPTCHA_VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify"; 28 | 29 | @Value("${google.recaptcha.secret}") 30 | private String reCaptchaSecretKey; 31 | 32 | private RestTemplateBuilder restTemplateBuilder; 33 | 34 | @Autowired 35 | public ReCaptchaService(RestTemplateBuilder restTemplateBuilder) { 36 | this.restTemplateBuilder = restTemplateBuilder; 37 | } 38 | 39 | public boolean verifyReCaptcha(String ip, String reCaptchaResponse) { 40 | Map body = new HashMap<>(); 41 | body.put("secret", reCaptchaSecretKey); 42 | body.put("response", reCaptchaResponse); 43 | body.put("remoteip", ip); 44 | 45 | LOGGER.debug("Request body for recaptcha: {}", body); 46 | ResponseEntity reCaptchaResponseEntity = 47 | restTemplateBuilder.build() 48 | .postForEntity(GOOGLE_RECAPTCHA_VERIFY_URL + 49 | "?secret={secret}&response={response}&remoteip={remoteip}", 50 | body, Map.class, body); 51 | 52 | LOGGER.debug("Response from recaptcha: {}", reCaptchaResponseEntity); 53 | 54 | Map responseBody = reCaptchaResponseEntity.getBody(); 55 | 56 | return (boolean) responseBody.get("success"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/admin/applicantList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 현재 필터에 해당하는 응모 수: 개 5 |
6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
응모 일자이메일유튜브 닉네임아이피RefererUserAgent핑거프린트중복 응모 여부중복 응모 처리중복 응모 처리자
25 |
26 | 27 |
28 | 29 | 43 | 44 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/rest/ApplicantListRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin.rest; 2 | 3 | import com.horyu1234.eventangel.domain.Applicant; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.factory.SessionAttributeNameFactory; 6 | import com.horyu1234.eventangel.service.ApplicantService; 7 | import com.horyu1234.eventangel.service.EventService; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import javax.servlet.http.HttpSession; 14 | import java.util.List; 15 | 16 | @RequestMapping("/admin/applicantList") 17 | @RestController 18 | public class ApplicantListRestController { 19 | private EventService eventService; 20 | private ApplicantService applicantService; 21 | 22 | @Autowired 23 | public ApplicantListRestController(EventService eventService, ApplicantService applicantService) { 24 | this.eventService = eventService; 25 | this.applicantService = applicantService; 26 | } 27 | 28 | @RequestMapping(value = "/getApplicant", method = RequestMethod.POST) 29 | public List getApplicant(String columnId, String columnName) { 30 | Event currentEvent = eventService.getCurrentEvent(); 31 | 32 | if (columnId == null || columnName == null) { 33 | return applicantService.getApplicantList(currentEvent.getEventId()); 34 | } else { 35 | return applicantService.getApplicantList(currentEvent.getEventId(), columnId, columnName); 36 | } 37 | } 38 | 39 | @RequestMapping(value = "/changeDuplicated", method = RequestMethod.POST) 40 | public String changeDuplicated(HttpSession session, 41 | String applyEmail, boolean isDuplicated) { 42 | Event currentEvent = eventService.getCurrentEvent(); 43 | 44 | if (isDuplicated) { 45 | String loginUsername = (String) session.getAttribute(SessionAttributeNameFactory.LOGIN_USERNAME); 46 | 47 | applicantService.updateApplicantDuplicated(currentEvent.getEventId(), applyEmail, loginUsername); 48 | } else { 49 | applicantService.updateApplicantNotDuplicated(currentEvent.getEventId(), applyEmail); 50 | } 51 | 52 | return "success"; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/ApplicantService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.google.common.collect.Lists; 4 | import com.horyu1234.eventangel.database.dao.ApplicantDAO; 5 | import com.horyu1234.eventangel.domain.Applicant; 6 | import com.horyu1234.eventangel.domain.DuplicatedApplicant; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | import javax.annotation.PostConstruct; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by horyu on 2018-04-03 15 | */ 16 | @Service 17 | public class ApplicantService { 18 | private ApplicantDAO applicantDAO; 19 | 20 | @PostConstruct 21 | public void init() { 22 | applicantDAO.createTableIfNotExist(); 23 | } 24 | 25 | @Autowired 26 | public void setApplicantDAO(ApplicantDAO applicantDAO) { 27 | this.applicantDAO = applicantDAO; 28 | } 29 | 30 | public void addApply(Applicant applicant) { 31 | applicantDAO.insertApplicant(applicant); 32 | } 33 | 34 | public Applicant getApply(int eventId, String email) { 35 | List applicantList = applicantDAO.getApplicant(eventId, email); 36 | return applicantList.isEmpty() ? null : applicantList.get(0); 37 | } 38 | 39 | public long getApplyCount(int eventId, boolean includeDuplicated) { 40 | return applicantDAO.getApplicantCount(eventId, includeDuplicated); 41 | } 42 | 43 | public long getApplyCount(int eventId, String ip) { 44 | return applicantDAO.getApplicantCount(eventId, ip); 45 | } 46 | 47 | public List getApplicantList(int eventId) { 48 | return Lists.newArrayList(applicantDAO.getApplicant(eventId)); 49 | } 50 | 51 | public List getApplicantList(int eventId, String whereKey, String whereValue) { 52 | return Lists.newArrayList(applicantDAO.getApplicant(eventId, whereKey, whereValue)); 53 | } 54 | 55 | public List getDuplicatedApplicant(int eventId, String columnName) { 56 | return applicantDAO.getDuplicatedApplicant(eventId, columnName); 57 | } 58 | 59 | public void updateApplicantNotDuplicated(int eventId, String applyEmail) { 60 | applicantDAO.updateApplicantNotDuplicated(eventId, applyEmail); 61 | } 62 | 63 | public void updateApplicantDuplicated(int eventId, String applyEmail, String dupCheckAdminName) { 64 | applicantDAO.updateApplicantDuplicated(eventId, applyEmail, dupCheckAdminName); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/EventWinnerService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.horyu1234.eventangel.database.dao.EventWinnerDAO; 4 | import com.horyu1234.eventangel.domain.Applicant; 5 | import com.horyu1234.eventangel.domain.EventWinner; 6 | import com.horyu1234.eventangel.domain.EventWinnerDetail; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | import javax.annotation.PostConstruct; 11 | import java.time.ZoneId; 12 | import java.time.ZonedDateTime; 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | /** 17 | * Created by horyu on 2018-04-15 18 | */ 19 | @Service 20 | public class EventWinnerService { 21 | private EventWinnerDAO eventWinnerDAO; 22 | private ApplicantService applicantService; 23 | 24 | @Autowired 25 | public EventWinnerService(EventWinnerDAO eventWinnerDAO, ApplicantService applicantService) { 26 | this.eventWinnerDAO = eventWinnerDAO; 27 | this.applicantService = applicantService; 28 | } 29 | 30 | @PostConstruct 31 | public void init() { 32 | eventWinnerDAO.createTableIfNotExist(); 33 | } 34 | 35 | public void resetEventWinner(int eventId) { 36 | eventWinnerDAO.resetEventWinner(eventId); 37 | } 38 | 39 | public void addEventWinner(int eventId, int prizeId, String applyEmail) { 40 | eventWinnerDAO.insertEventWinner(eventId, prizeId, applyEmail, ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime()); 41 | } 42 | 43 | public List getWinnerList(int eventId) { 44 | List winnerList = eventWinnerDAO.getWinnerList(eventId); 45 | 46 | return winnerList.stream() 47 | .map(winner -> { 48 | Applicant applicant = applicantService.getApply(eventId, winner.getApplyEmail()); 49 | 50 | EventWinnerDetail eventWinnerDetail = EventWinnerDetail.fromEventWinner(winner); 51 | eventWinnerDetail.setApplicant(applicant); 52 | 53 | return eventWinnerDetail; 54 | }) 55 | .collect(Collectors.toList()); 56 | } 57 | 58 | public List hidePrivacy(List eventWinnerDetails) { 59 | return eventWinnerDetails.stream() 60 | .peek(eventWinnerDetail -> { 61 | Applicant applicant = eventWinnerDetail.getApplicant(); 62 | applicant.hidePrivacy(); 63 | 64 | eventWinnerDetail.setApplicant(applicant); 65 | }).collect(Collectors.toList()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.Duplicated.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.Duplicated=function(){var a=this;a.init=function(){a.bindEvents();a.updateTable(a.getCurrentColumnId())};a.bindEvents=function(){$(".columnNameButton").change(function(){var b=$(this).attr("id");a.updateTable(b)})};a.updateTable=function(b){$("#loading-modal").modal({backdrop:"static",keyboard:!1});$.ajax({type:"POST",url:"./getDuplicated",data:{columnName:b},timeout:1E4}).done(function(b){$("#loading-modal").modal("hide");Array.isArray(b)?a.updatePagination(b):($("#fail-modal").modal({backdrop:"static", 3 | keyboard:!1}),setTimeout(function(){location.reload()},4E3))})};a.updatePagination=function(b){$(".table-pagination").pagination({className:"paginationjs-theme-blue paginationjs-big",dataSource:b,pageSize:10,autoHidePrevious:!0,autoHideNext:!0,callback:function(b,c){a.renderTable(b)}})};a.renderTable=function(b){var e=$(".duplicated-table");e.find(".tableColumnName").text(a.getCurrentColumnName());var c=e.find("tbody");c.empty();b.forEach(function(b){var d=$("\x3ctr\x3e\x3c/tr\x3e");d.append($("\x3ctd\x3e").html('\x3ca target\x3d"_blank" href\x3d"/admin/applicantList/?columnId\x3d'+ 4 | a.getCurrentColumnId()+"\x26columnName\x3d"+b.columnName+'"\x3e'+b.columnName+"\x3c/a\x3e"));d.append($('\x3ctd class\x3d"duplicated-count"\x3e').text(b.duplicatedCount+"\uac1c"));"IP_ADDRESS"===a.getCurrentColumnId()?d.append($('\x3ctd class\x3d"remarks"\x3e').text(a.getCarrierInformation(b.columnName))):d.append($('\x3ctd class\x3d"remarks"\x3e').text(""));c.append(d)})};a.getCarrierInformation=function(b){var e="115.161 121.190 122.202 122.32 175.202 223.32 223.33 223.62 223.38 223.39 223.57".split(" "), 5 | c=["39.7","110.70","175.223","175.252","211.246"],f="39.7 110.70 175.223 175.252 210.125 211.246".split(" "),d=["61.43","211.234"],g=["114.200","117.111","211.36","106.102","125.188"];return a.containsIpRange(["203.226","211.234"],b)?"\ud1b5\uc2e0\uc0ac \uc544\uc774\ud53c (SKT 3G)":a.containsIpRange(e,b)?"\ud1b5\uc2e0\uc0ac \uc544\uc774\ud53c (SKT LTE)":a.containsIpRange(c,b)?"\ud1b5\uc2e0\uc0ac \uc544\uc774\ud53c (KT 3G/LTE)":a.containsIpRange(f,b)?"\ud1b5\uc2e0\uc0ac \uc544\uc774\ud53c (LTE)":a.containsIpRange(d, 6 | b)?"\ud1b5\uc2e0\uc0ac \uc544\uc774\ud53c (LG U+ 3G)":a.containsIpRange(g,b)?"\ud1b5\uc2e0\uc0ac \uc544\uc774\ud53c (LG U+ LTE)":""};a.containsIpRange=function(a,e){var c=!1;a.forEach(function(a){e.startsWith(a)&&(c=!0)});return c};a.getCurrentColumnId=function(){return $(".columnNameBtnGroup .active input").attr("id")};a.getCurrentColumnName=function(){return $(".columnNameBtnGroup .active input").attr("name")};return{init:function(){a.init()}}}; 7 | //# sourceMappingURL=Horyu.View.Duplicated.min.js.map -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/EventService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.horyu1234.eventangel.constant.EventDetailStatus; 4 | import com.horyu1234.eventangel.constant.EventStatus; 5 | import com.horyu1234.eventangel.database.dao.EventDAO; 6 | import com.horyu1234.eventangel.domain.Event; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.cache.annotation.CacheEvict; 9 | import org.springframework.cache.annotation.Cacheable; 10 | import org.springframework.stereotype.Service; 11 | 12 | import javax.annotation.PostConstruct; 13 | import java.time.LocalDateTime; 14 | import java.time.ZoneId; 15 | import java.time.ZonedDateTime; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by horyu on 2018-04-06 20 | */ 21 | @Service 22 | public class EventService { 23 | private EventDAO eventDAO; 24 | 25 | @PostConstruct 26 | public void init() { 27 | eventDAO.createTableIfNotExist(); 28 | } 29 | 30 | @Autowired 31 | public void setEventDAO(EventDAO eventDAO) { 32 | this.eventDAO = eventDAO; 33 | } 34 | 35 | @CacheEvict(value = {"event.current_event", "event.list"}, allEntries = true) 36 | public void updateEvent(Event event) { 37 | eventDAO.updateOrInsertEvent(event); 38 | } 39 | 40 | @Cacheable(value = "event.current_event") 41 | public Event getCurrentEvent() { 42 | return eventDAO.getCurrentEvent(); 43 | } 44 | 45 | @Cacheable(value = "event.list") 46 | public List getEventList() { 47 | return eventDAO.getEventList(); 48 | } 49 | 50 | public EventDetailStatus getEventDetailStatus(Event event) { 51 | if (event.getEventStatus() == EventStatus.CLOSE) { 52 | return EventDetailStatus.CLOSE; 53 | } else if (event.getEventStatus() == EventStatus.LOTTERY) { 54 | return EventDetailStatus.LOTTERY; 55 | } 56 | 57 | LocalDateTime currentTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime(); 58 | if (currentTime.isBefore(event.getEventStartTime())) { 59 | return EventDetailStatus.START_SOON; 60 | } else if (currentTime.isAfter(event.getEventEndTime())) { 61 | return EventDetailStatus.ALREADY_END; 62 | } else { 63 | return EventDetailStatus.OPEN; 64 | } 65 | } 66 | 67 | public void newEvent() { 68 | Event event = new Event(); 69 | event.setEventTitle("허수아비 X차 이벤트"); 70 | event.setEventDetail("이벤트 세부 일정"); 71 | event.setEventStatus(EventStatus.CLOSE); 72 | event.setEventStartTime(ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime()); 73 | event.setEventEndTime(ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime()); 74 | 75 | updateEvent(event); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/resources/templates/view/admin/duplicated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 현재 이벤트에서 다음 타입의 값이 중복되는 목록입니다. 5 |

6 | 7 |
8 | 11 | 15 | 18 | 21 |
22 |
23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
로딩 중중복 개수비고
35 |
36 | 37 |
38 | 39 | 53 | 54 | 68 | 69 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventHistory.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"Horyu.View.EventHistory.min.js", 4 | "lineCount":5, 5 | "mappings":"AAEA,IAAIA,MAAQC,MAAAD,MAARA,EAAwB,EAC5BA,MAAAE,KAAA,CAAaD,MAAAD,MAAAE,KAAb,EAAkC,EAClCF;KAAAE,KAAAC,aAAA,CAA0BC,QAAQ,CAACC,CAAD,CAAU,CACxC,IAAIC,EAAQ,IAOZA,EAAAD,QAAA,CAAgBE,CAAAC,OAAA,CALKC,CACjBC,UAAW,EADMD,CAEjBE,kBAAmB,EAFFF,CAKL,CAAyBJ,CAAzB,CAEhBC,EAAAM,KAAA,CAAaC,QAAQ,EAAG,CACpBP,CAAAQ,yBAAA,EACAR,EAAAS,YAAA,EACAT,EAAAU,WAAA,EAHoB,CAMxBV,EAAAQ,yBAAA,CAAiCG,QAAQ,EAAG,CACxC,IAAIC,EAAiBX,CAAA,CAAE,iBAAF,CACrBW,EAAAC,YAAA,CAA2B,WAA3B,CACAD,EAAAE,SAAA,CAAwB,gBAAxB,CAHwC,CAM5Cd,EAAAS,YAAA,CAAoBM,QAAQ,EAAG,CAG3B,IAAIC,EAFSf,CAAAgB,CAAE,sBAAFA,CAEIC,KAAA,CAAY,OAAZ,CACjBF,EAAAG,MAAA,EAEAnB,EAAAD,QAAAK,UAAAgB,QAAA,CAAgC,QAAQ,CAACC,CAAD,CAAQ,CAC5C,IAAIC,EAAMrB,CAAA,CAAE,uBAAF,CACVqB,EAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAuB,KAAA,CAAeH,CAAAI,QAAf,CAAX,CACAH;CAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAuB,KAAA,CAAeH,CAAAK,WAAf,CAAX,CACAJ,EAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAuB,KAAA,CAAeH,CAAAM,YAAf,CAAX,CACAL,EAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAuB,KAAA,CAAexB,CAAA4B,mBAAA,CAAyBP,CAAAQ,YAAzB,CAAf,CAAX,CACAP,EAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAA6B,KAAA,CAAeC,MAAA,CAAOV,CAAAW,eAAP,CAAAC,OAAA,CAAoC,oEAApC,CAAf,CAAX,CACAX,EAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAA6B,KAAA,CAAeC,MAAA,CAAOV,CAAAa,aAAP,CAAAD,OAAA,CAAkC,oEAAlC,CAAf,CAAX,CAEA,KAAIE,EAAiBnC,CAAAD,QAAAM,kBAAA,CAAgCgB,CAAAI,QAAhC,CACD,EAApB,CAAIJ,CAAAI,QAAJ,CACIH,CAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAuB,KAAA,CAAeW,CAAf;AAAgC,QAAhC,CAAX,CADJ,CAGIb,CAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAuB,KAAA,CAAe,GAAf,CAAX,CAGAY,EAAAA,CAAkBnC,CAAA,CAAE,+FAAF,CAAAuB,KAAA,CACZ,8CADY,CAAAa,KAAA,CAEZ,eAFY,CAEKhB,CAAAI,QAFL,CAItBH,EAAAC,OAAA,CAAWtB,CAAA,CAAE,YAAF,CAAAsB,OAAA,CAAiBa,CAAjB,CAAX,CAEApB,EAAAO,OAAA,CAAkBD,CAAlB,CAtB4C,CAAhD,CAN2B,CAgC/BtB,EAAA4B,mBAAA,CAA2BU,QAAQ,CAACT,CAAD,CAAc,CAC7C,MAAoB,MAApB,GAAIA,CAAJ,CACW,qBADX,CAE2B,OAApB,GAAIA,CAAJ,CACI,2BADJ,CAEoB,SAApB,GAAIA,CAAJ,CACI,2BADJ,CAGIA,CARkC,CAYjD7B,EAAAU,WAAA,CAAmB6B,QAAQ,EAAG,CAC1BtC,CAAA,CAAE,eAAF,CAAAuC,MAAA,CAAyB,QAAQ,CAACnB,CAAD,CAAQ,CACjCI,CAAAA;AAAUxB,CAAA,CAAEoB,CAAAoB,OAAF,CAAAJ,KAAA,CAAqB,eAArB,CACdK,SAAAC,KAAA,CAAgB,SAAhB,CAA4BlB,CAFS,CAAzC,CAD0B,CAO9B,OAAO,CACHnB,KAAMA,QAAQ,EAAG,CACbN,CAAAM,KAAA,EADa,CADd,CAzEiC;", 6 | "sources":["/js/admin/Horyu.View.EventHistory.js"], 7 | "names":["Horyu","window","View","EventHistory","Horyu.View.EventHistory","options","_this","$","extend","defaultOptions","eventList","applicantCountMap","init","_this.init","changeMainContainerWidth","updateTable","bindEvents","_this.changeMainContainerWidth","$mainContainer","removeClass","addClass","_this.updateTable","$tableBody","$table","find","empty","forEach","event","$tr","append","text","eventId","eventTitle","eventDetail","getEventStatusText","eventStatus","html","moment","eventStartTime","format","eventEndTime","applicantCount","$eventDetailBtn","attr","_this.getEventStatusText","_this.bindEvents","click","target","location","href"] 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/PrizeController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.domain.Prize; 6 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 7 | import com.horyu1234.eventangel.form.PrizeSaveForm; 8 | import com.horyu1234.eventangel.service.CompanyService; 9 | import com.horyu1234.eventangel.service.EventService; 10 | import com.horyu1234.eventangel.service.PrizeService; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.ui.Model; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | 17 | /** 18 | * Created by horyu on 2018-04-04 19 | */ 20 | @RequestMapping("/admin/prizeSetting") 21 | @Controller 22 | public class PrizeController { 23 | private EventService eventService; 24 | private CompanyService companyService; 25 | private PrizeService prizeService; 26 | 27 | @Autowired 28 | public void setEventService(EventService eventService) { 29 | this.eventService = eventService; 30 | } 31 | 32 | @Autowired 33 | public void setCompanyService(CompanyService companyService) { 34 | this.companyService = companyService; 35 | } 36 | 37 | @Autowired 38 | public void setPrizeService(PrizeService prizeService) { 39 | this.prizeService = prizeService; 40 | } 41 | 42 | @RequestMapping(value = "/", method = RequestMethod.GET) 43 | public String prizeSetting(Model model) { 44 | Event currentEvent = eventService.getCurrentEvent(); 45 | 46 | model.addAttribute(ModelAttributeNameFactory.EVENT_STATUS, currentEvent.getEventStatus()); 47 | model.addAttribute("companyList", companyService.getCompanyList(currentEvent.getEventId())); 48 | model.addAttribute("prizeList", prizeService.getCompanyGiftData(currentEvent.getEventId())); 49 | 50 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_PRIZE_SETTING.toView()); 51 | 52 | return View.LAYOUT.getTemplateName(); 53 | } 54 | 55 | @RequestMapping(value = "/savePrize", method = RequestMethod.POST) 56 | public String savePrize(PrizeSaveForm prizeSaveForm) { 57 | Event currentEvent = eventService.getCurrentEvent(); 58 | 59 | Prize prize = new Prize(); 60 | prize.setEventId(currentEvent.getEventId()); 61 | prize.setPrizeId(prizeSaveForm.getPrizeId()); 62 | prize.setCompanyId(prizeSaveForm.getCompanyId()); 63 | prize.setPrizeName(prizeSaveForm.getPrizeName()); 64 | prize.setPrizeAmount(prizeSaveForm.getPrizeAmount()); 65 | 66 | prizeService.savePrize(prize); 67 | 68 | return View.ADMIN_PRIZE_SETTING.toRedirect(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/CompanyAndPrize.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | /** 4 | * Created by horyu on 2018-04-14 5 | */ 6 | public class CompanyAndPrize { 7 | private int prizeId; 8 | private int companyId; 9 | private String companyName; 10 | private String companyDetail; 11 | private String companyLogoImageFileName; 12 | private String prizeName; 13 | private int prizeAmount; 14 | 15 | public CompanyAndPrize() { 16 | } 17 | 18 | public CompanyAndPrize(Company company, Prize prize) { 19 | this.prizeId = prize.getPrizeId(); 20 | this.companyId = prize.getCompanyId(); 21 | this.companyName = company.getCompanyName(); 22 | this.companyDetail = company.getCompanyDetail(); 23 | this.companyLogoImageFileName = company.getCompanyLogoImageFileName(); 24 | this.prizeName = prize.getPrizeName(); 25 | this.prizeAmount = prize.getPrizeAmount(); 26 | } 27 | 28 | public int getPrizeId() { 29 | return prizeId; 30 | } 31 | 32 | public void setPrizeId(int prizeId) { 33 | this.prizeId = prizeId; 34 | } 35 | 36 | public int getCompanyId() { 37 | return companyId; 38 | } 39 | 40 | public void setCompanyId(int companyId) { 41 | this.companyId = companyId; 42 | } 43 | 44 | public String getCompanyName() { 45 | return companyName; 46 | } 47 | 48 | public void setCompanyName(String companyName) { 49 | this.companyName = companyName; 50 | } 51 | 52 | public String getPrizeName() { 53 | return prizeName; 54 | } 55 | 56 | public void setPrizeName(String prizeName) { 57 | this.prizeName = prizeName; 58 | } 59 | 60 | public String getCompanyDetail() { 61 | return companyDetail; 62 | } 63 | 64 | public void setCompanyDetail(String companyDetail) { 65 | this.companyDetail = companyDetail; 66 | } 67 | 68 | public String getCompanyLogoImageFileName() { 69 | return companyLogoImageFileName; 70 | } 71 | 72 | public void setCompanyLogoImageFileName(String companyLogoImageFileName) { 73 | this.companyLogoImageFileName = companyLogoImageFileName; 74 | } 75 | 76 | public int getPrizeAmount() { 77 | return prizeAmount; 78 | } 79 | 80 | public void setPrizeAmount(int prizeAmount) { 81 | this.prizeAmount = prizeAmount; 82 | } 83 | 84 | public CompanyAndPrize copy() { 85 | CompanyAndPrize companyAndPrize = new CompanyAndPrize(); 86 | companyAndPrize.setPrizeId(this.prizeId); 87 | companyAndPrize.setCompanyId(this.companyId); 88 | companyAndPrize.setCompanyName(this.companyName); 89 | companyAndPrize.setPrizeName(this.prizeName); 90 | companyAndPrize.setCompanyDetail(this.companyDetail); 91 | companyAndPrize.setPrizeAmount(this.prizeAmount); 92 | 93 | return companyAndPrize; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventHistory.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Horyu = window.Horyu || {}; 4 | Horyu.View = window.Horyu.View || {}; 5 | Horyu.View.EventHistory = function(options) { 6 | var _this = this; 7 | 8 | var defaultOptions = { 9 | eventList: [], 10 | applicantCountMap: {} 11 | }; 12 | 13 | _this.options = $.extend(defaultOptions, options); 14 | 15 | _this.init = function() { 16 | _this.changeMainContainerWidth(); 17 | _this.updateTable(); 18 | _this.bindEvents(); 19 | }; 20 | 21 | _this.changeMainContainerWidth = function() { 22 | var $mainContainer = $('#main-container'); 23 | $mainContainer.removeClass('container'); 24 | $mainContainer.addClass('container-full'); 25 | }; 26 | 27 | _this.updateTable = function() { 28 | var $table = $('.event-history-table'); 29 | 30 | var $tableBody = $table.find('tbody'); 31 | $tableBody.empty(); 32 | 33 | _this.options.eventList.forEach(function(event) { 34 | var $tr = $(''); 35 | $tr.append($('').text(event.eventId)); 36 | $tr.append($('').text(event.eventTitle)); 37 | $tr.append($('').text(event.eventDetail)); 38 | $tr.append($('').text(_this.getEventStatusText(event.eventStatus))); 39 | $tr.append($('').html(moment(event.eventStartTime).format('YYYY년 MMMM D일 dddd
A h시 mm분 ss초'))); 40 | $tr.append($('').html(moment(event.eventEndTime).format('YYYY년 MMMM D일 dddd
A h시 mm분 ss초'))); 41 | 42 | var applicantCount = _this.options.applicantCountMap[event.eventId]; 43 | if (event.eventId > 5) { 44 | $tr.append($('').text(applicantCount + '개')); 45 | } else { 46 | $tr.append($('').text('-')); 47 | } 48 | 49 | var $eventDetailBtn = $('') 50 | .text('이벤트 결과 확인') 51 | .attr('data-event-id', event.eventId); 52 | 53 | $tr.append($('').append($eventDetailBtn)); 54 | 55 | $tableBody.append($tr); 56 | }); 57 | }; 58 | 59 | _this.getEventStatusText = function(eventStatus) { 60 | if (eventStatus === 'OPEN') { 61 | return '응모 중'; 62 | } else if (eventStatus === 'CLOSE') { 63 | return '응모 닫힘'; 64 | } else if (eventStatus === 'LOTTERY') { 65 | return '추첨 진행'; 66 | } else { 67 | return eventStatus; 68 | } 69 | }; 70 | 71 | _this.bindEvents = function() { 72 | $('.viewEventBtn').click(function(event) { 73 | var eventId = $(event.target).attr('data-event-id'); 74 | location.href = './view/' + eventId; 75 | }); 76 | }; 77 | 78 | return { 79 | init: function() { 80 | _this.init(); 81 | } 82 | }; 83 | }; -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/rest/CompanyLogoImageRestController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.rest; 2 | 3 | import com.horyu1234.eventangel.domain.Company; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.service.CompanyService; 6 | import com.horyu1234.eventangel.service.EventService; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.http.MediaType; 11 | import org.springframework.util.StreamUtils; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RequestMethod; 14 | import org.springframework.web.bind.annotation.RestController; 15 | 16 | import javax.servlet.http.HttpServletResponse; 17 | import java.io.File; 18 | import java.io.FileInputStream; 19 | import java.io.IOException; 20 | import java.io.InputStream; 21 | 22 | @RestController 23 | public class CompanyLogoImageRestController { 24 | private static final Logger LOGGER = LoggerFactory.getLogger(CompanyLogoImageRestController.class); 25 | private EventService eventService; 26 | private CompanyService companyService; 27 | 28 | @Autowired 29 | public CompanyLogoImageRestController(EventService eventService, CompanyService companyService) { 30 | this.eventService = eventService; 31 | this.companyService = companyService; 32 | } 33 | 34 | @RequestMapping(value = "/companyLogo", method = RequestMethod.GET) 35 | public void companyLogoImage(HttpServletResponse response, int companyId) { 36 | Event currentEvent = eventService.getCurrentEvent(); 37 | 38 | Company company = companyService.getCompany(currentEvent.getEventId(), companyId); 39 | 40 | String companyLogoImageFileName = company.getCompanyLogoImageFileName(); 41 | 42 | File companyLogoImage = companyService.getCompanyLogoImage(currentEvent.getEventId(), companyId); 43 | if (companyLogoImage == null) { 44 | response.setStatus(HttpServletResponse.SC_NOT_FOUND); 45 | return; 46 | } 47 | 48 | response.setContentType(getImageType(companyLogoImageFileName)); 49 | 50 | try (InputStream inputStream = new FileInputStream(companyLogoImage)) { 51 | StreamUtils.copy(inputStream, response.getOutputStream()); 52 | } catch (IOException ignored) { 53 | } 54 | } 55 | 56 | private String getImageType(String fileName) { 57 | String extension = fileName.split("\\.")[1]; 58 | 59 | switch (extension.toLowerCase()) { 60 | case "png": 61 | return MediaType.IMAGE_PNG_VALUE; 62 | case "jpg": 63 | case "jpeg": 64 | return MediaType.IMAGE_JPEG_VALUE; 65 | case "gif": 66 | return MediaType.IMAGE_GIF_VALUE; 67 | default: 68 | return MediaType.IMAGE_PNG_VALUE; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventSetting.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.EventSetting=function(c){var a=this;a.options=$.extend({eventStartTime:0,eventEndTime:0},c);a.init=function(){a.initDateRangePicker();a.bindEvents();a.updateVisibleStatus("OPEN"===a.getOpenEventBtnId())};a.initDateRangePicker=function(){$("#eventTerm").daterangepicker({timePicker:!0,timePickerIncrement:1,timePickerSeconds:!0,showDropdowns:!0,todayHighlight:!0,startDate:moment.unix(a.options.eventStartTime),endDate:moment.unix(a.options.eventEndTime),dateLimit:{year:1},locale:{format:"YYYY\ub144 MM\uc6d4 DD\uc77c A h\uc2dc mm\ubd84 ss\ucd08", 3 | applyLabel:"\uc801\uc6a9",cancelLabel:"\ucde8\uc18c",daysOfWeek:"\uc77c\uc6d4\ud654\uc218\ubaa9\uae08\ud1a0".split(""),monthNames:"1\uc6d4 2\uc6d4 3\uc6d4 4\uc6d4 5\uc6d4 6\uc6d4 7\uc6d4 8\uc6d4 9\uc6d4 10\uc6d4 11\uc6d4 12\uc6d4".split(" ")}})};a.bindEvents=function(){$(".eventStatusButton").change(function(){a.updateVisibleStatus("OPEN"===$(this).attr("id"))});$(".submitBtn").click(function(){var b=$("#eventTerm").data("daterangepicker");$("#eventStatus").val(a.getOpenEventBtnId());$("#eventStartTime").val(b.startDate.unix()); 4 | $("#eventEndTime").val(b.endDate.unix());$("#eventSettingForm").submit()});$(".endEventBtn").click(function(){$("#end-event-modal").modal({backdrop:"static",keyboard:!1})});$("#endEventConfirmBtn").click(function(){$("#endEventConfirmBtn").html("\ucc98\ub9ac \uc911\uc785\ub2c8\ub2e4.");$("#endEventConfirmBtn").attr("disabled","");$(".abortBtn").css("visibility","hidden");$.ajax({type:"GET",url:"./endEvent",timeout:5E3}).done(function(){$("#endEventConfirmBtn").html("\uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4."); 5 | setTimeout(function(){location.reload()},500)}).fail(function(a){$("#endEventConfirmBtn").html("\ud1b5\uc2e0\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \uc7a0\uc2dc \ud6c4 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.");setTimeout(function(){location.reload()},3E3)})});$(".resetEventWinner").click(function(){$("#reset-event-winner-modal").modal({backdrop:"static",keyboard:!1})});$("#resetEventWinnerConfirmBtn").click(function(){$("#resetEventWinnerConfirmBtn").html("\ucc98\ub9ac \uc911\uc785\ub2c8\ub2e4."); 6 | $("#resetEventWinnerConfirmBtn").attr("disabled","");$(".abortBtn").css("visibility","hidden");$.ajax({type:"GET",url:"./resetEventWinner",timeout:5E3}).done(function(){$("#resetEventWinnerConfirmBtn").html("\uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.");setTimeout(function(){location.reload()},500)}).fail(function(a){$("#resetEventWinnerConfirmBtn").html("\ud1b5\uc2e0\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \uc7a0\uc2dc \ud6c4 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.");setTimeout(function(){location.reload()}, 7 | 3E3)})})};a.getOpenEventBtnId=function(){return $(".eventStatusBtnGroup .active input").attr("id")};a.updateVisibleStatus=function(a){a?$(".eventOpenSettingGroup").show(500):$(".eventOpenSettingGroup").hide(500)};return{init:function(){a.init()}}}; 8 | //# sourceMappingURL=Horyu.View.EventSetting.min.js.map -------------------------------------------------------------------------------- /src/main/resources/templates/view/apply/wrongWay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
6 | 현재 0명이 이벤트 응모를 하였습니다. 7 |
8 | 9 |
10 |
11 |
12 | 이벤트 응모 방법 13 |
14 | 15 |

1. 네이버 접속 후 "{검색어}" 검색 (https://www.naver.com/) 18 |

19 | 20 |
21 |
22 | 23 |
25 |
도움을 주신 회사와 상품 목록
26 |
27 |
28 | 29 |
31 |
현재 당첨자 목록
32 |
33 |
34 | 앞으로 있을 추첨 방송을 기대해주시기 바랍니다. 35 |

36 | 추첨 방송이 시작되면, 여기에도 당첨자 목록이 표시됩니다. 37 |
38 |
39 |
40 | 41 |
43 |
현재 당첨자 목록
44 |
45 |
46 |
47 |
48 | 49 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/EventHistoryController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 6 | import com.horyu1234.eventangel.service.ApplicantService; 7 | import com.horyu1234.eventangel.service.EventService; 8 | import com.horyu1234.eventangel.service.EventWinnerService; 9 | import com.horyu1234.eventangel.service.PrizeService; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.Model; 13 | import org.springframework.web.bind.annotation.PathVariable; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestMethod; 16 | 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | /** 22 | * Created by horyu on 2018-04-16 23 | */ 24 | @RequestMapping("/admin/eventHistory") 25 | @Controller 26 | public class EventHistoryController { 27 | private EventService eventService; 28 | private PrizeService prizeService; 29 | private EventWinnerService eventWinnerService; 30 | private ApplicantService applicantService; 31 | 32 | @Autowired 33 | public EventHistoryController(EventService eventService, PrizeService prizeService, EventWinnerService eventWinnerService, ApplicantService applicantService) { 34 | this.eventService = eventService; 35 | this.prizeService = prizeService; 36 | this.eventWinnerService = eventWinnerService; 37 | this.applicantService = applicantService; 38 | } 39 | 40 | @RequestMapping(value = "/", method = RequestMethod.GET) 41 | public String eventHistory(Model model) { 42 | List eventList = eventService.getEventList(); 43 | Map applicantCountMap = new HashMap<>(); 44 | 45 | for (Event event : eventList) { 46 | int eventId = event.getEventId(); 47 | 48 | long applyCount = applicantService.getApplyCount(eventId, true); 49 | applicantCountMap.put(eventId, applyCount); 50 | } 51 | 52 | model.addAttribute("eventList", eventList); 53 | model.addAttribute("applicantCountMap", applicantCountMap); 54 | 55 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_EVENT_HISTORY.toView()); 56 | 57 | return View.LAYOUT.getTemplateName(); 58 | } 59 | 60 | @RequestMapping(value = "/view/{eventId}", method = RequestMethod.GET) 61 | public String eventHistory(Model model, @PathVariable int eventId) { 62 | model.addAttribute("companyGiftData", prizeService.getCompanyGiftData(eventId)); 63 | model.addAttribute("eventWinnerData", eventWinnerService.getWinnerList(eventId)); 64 | 65 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_EVENT_HISTORY_VIEW.toView()); 66 | 67 | return View.LAYOUT.getTemplateName(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/dao/EventDAO.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.dao; 2 | 3 | import com.horyu1234.eventangel.database.mapper.EventMapper; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.factory.DateFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.jdbc.core.BeanPropertyRowMapper; 8 | import org.springframework.jdbc.core.JdbcTemplate; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * Created by horyu on 2018-04-15 15 | */ 16 | @Repository 17 | public class EventDAO { 18 | private JdbcTemplate jdbcTemplate; 19 | private EventMapper eventMapper; 20 | 21 | @Autowired 22 | public EventDAO(JdbcTemplate jdbcTemplate, EventMapper eventMapper) { 23 | this.jdbcTemplate = jdbcTemplate; 24 | this.eventMapper = eventMapper; 25 | } 26 | 27 | public void createTableIfNotExist() { 28 | jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `EVENT` ( " + 29 | "`EVENT_ID` INT(11) NOT NULL AUTO_INCREMENT, " + 30 | "`EVENT_TITLE` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 31 | "`EVENT_DETAIL` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 32 | "`EVENT_STATUS` VARCHAR(10) NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 33 | "`EVENT_START_TIME` DATETIME NOT NULL, " + 34 | "`EVENT_END_TIME` DATETIME NOT NULL, " + 35 | "PRIMARY KEY (`EVENT_ID`) " + 36 | ") " + 37 | "COLLATE='utf8mb4_unicode_ci' " + 38 | "ENGINE=InnoDB;"); 39 | } 40 | 41 | public Event getCurrentEvent() { 42 | return jdbcTemplate.queryForObject( 43 | "SELECT * FROM `EVENT` " + 44 | "ORDER BY EVENT_ID " + 45 | "DESC LIMIT 1;", 46 | eventMapper); 47 | } 48 | 49 | public List getEventList() { 50 | return jdbcTemplate.query( 51 | "SELECT * FROM `EVENT` " + 52 | "ORDER BY EVENT_ID " + 53 | "DESC;", 54 | new BeanPropertyRowMapper<>(Event.class)); 55 | } 56 | 57 | public void updateOrInsertEvent(Event event) { 58 | String eventStartTime = DateFactory.DATABASE_FORMAT.format(event.getEventStartTime()); 59 | String eventEndTime = DateFactory.DATABASE_FORMAT.format(event.getEventEndTime()); 60 | 61 | jdbcTemplate.update("INSERT INTO `EVENT` (EVENT_ID, EVENT_TITLE, EVENT_DETAIL, EVENT_STATUS, EVENT_START_TIME, EVENT_END_TIME) VALUES (?, ?, ?, ?, ?, ?) " + 62 | "ON DUPLICATE KEY UPDATE EVENT_TITLE = ?, EVENT_DETAIL = ?, EVENT_STATUS = ?, EVENT_START_TIME = ?, EVENT_END_TIME = ?;", 63 | event.getEventId(), event.getEventTitle(), event.getEventDetail(), event.getEventStatus().name(), eventStartTime, eventEndTime, 64 | event.getEventTitle(), event.getEventDetail(), event.getEventStatus().name(), eventStartTime, eventEndTime); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/dao/PrizeDAO.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.dao; 2 | 3 | import com.horyu1234.eventangel.domain.Prize; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.jdbc.core.BeanPropertyRowMapper; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by horyu on 2018-04-15 13 | */ 14 | @Repository 15 | public class PrizeDAO { 16 | private JdbcTemplate jdbcTemplate; 17 | 18 | @Autowired 19 | public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { 20 | this.jdbcTemplate = jdbcTemplate; 21 | } 22 | 23 | public void createTableIfNotExist() { 24 | jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `PRIZE` ( " + 25 | "`EVENT_ID` INT(11) NOT NULL, " + 26 | "`PRIZE_ID` INT(11) NOT NULL, " + 27 | "`COMPANY_ID` INT(11) NOT NULL, " + 28 | "`PRIZE_NAME` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 29 | "`PRIZE_AMOUNT` INT(11) NOT NULL, " + 30 | "PRIMARY KEY (`EVENT_ID`, `PRIZE_ID`) " + 31 | ") " + 32 | "COLLATE='utf8mb4_unicode_ci' " + 33 | "ENGINE=InnoDB;"); 34 | } 35 | 36 | public List getPrizeList(int eventId) { 37 | return jdbcTemplate.query( 38 | "SELECT * FROM `PRIZE` " + 39 | "WHERE EVENT_ID = ? " + 40 | "ORDER BY `PRIZE_ID` " + 41 | "DESC;", 42 | new Object[]{eventId}, 43 | new BeanPropertyRowMapper<>(Prize.class)); 44 | } 45 | 46 | public int getMaxPrizeId(int eventId) { 47 | return jdbcTemplate.queryForObject( 48 | "SELECT MAX(PRIZE_ID) " + 49 | "FROM `PRIZE` " + 50 | "WHERE EVENT_ID = ?;", 51 | new Object[]{eventId}, 52 | Integer.class); 53 | } 54 | 55 | public void updateOrInsertPrize(Prize prize) { 56 | jdbcTemplate.update("INSERT INTO `PRIZE` (EVENT_ID, PRIZE_ID, COMPANY_ID, PRIZE_NAME, PRIZE_AMOUNT) VALUES (?, ?, ?, ?, ?) " + 57 | "ON DUPLICATE KEY UPDATE PRIZE_ID = ?, COMPANY_ID = ?, PRIZE_NAME = ?, PRIZE_AMOUNT = ?;", 58 | prize.getEventId(), prize.getPrizeId(), prize.getCompanyId(), prize.getPrizeName(), prize.getPrizeAmount(), 59 | prize.getPrizeId(), prize.getCompanyId(), prize.getPrizeName(), prize.getPrizeAmount()); 60 | } 61 | 62 | public void deletePrize(int eventId, int prizeId) { 63 | jdbcTemplate.update("DELETE FROM `PRIZE` " + 64 | "WHERE EVENT_ID = ? AND PRIZE_ID = ?", 65 | eventId, prizeId); 66 | } 67 | 68 | public void deletePrizeByCompanyId(int eventId, int companyId) { 69 | jdbcTemplate.update("DELETE FROM `PRIZE` " + 70 | "WHERE EVENT_ID = ? AND COMPANY_ID = ?", 71 | eventId, companyId); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/CompanySettingController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.domain.Company; 5 | import com.horyu1234.eventangel.domain.Event; 6 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 7 | import com.horyu1234.eventangel.form.CompanySaveForm; 8 | import com.horyu1234.eventangel.service.CompanyService; 9 | import com.horyu1234.eventangel.service.EventService; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.Model; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | import org.springframework.web.bind.annotation.RequestParam; 16 | import org.springframework.web.multipart.MultipartFile; 17 | 18 | /** 19 | * Created by horyu on 2018-04-04 20 | */ 21 | @RequestMapping("/admin/companySetting") 22 | @Controller 23 | public class CompanySettingController { 24 | private EventService eventService; 25 | private CompanyService companyService; 26 | 27 | @Autowired 28 | public void setEventService(EventService eventService) { 29 | this.eventService = eventService; 30 | } 31 | 32 | @Autowired 33 | public void setCompanyService(CompanyService companyService) { 34 | this.companyService = companyService; 35 | } 36 | 37 | @RequestMapping(value = "/", method = RequestMethod.GET) 38 | public String companySetting(Model model) { 39 | Event currentEvent = eventService.getCurrentEvent(); 40 | 41 | model.addAttribute("companyList", companyService.getCompanyList(currentEvent.getEventId())); 42 | model.addAttribute(ModelAttributeNameFactory.EVENT_STATUS, currentEvent.getEventStatus()); 43 | 44 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_COMPANY_SETTING.toView()); 45 | 46 | return View.LAYOUT.getTemplateName(); 47 | } 48 | 49 | @RequestMapping(value = "/saveCompany", method = RequestMethod.POST) 50 | public String saveCompany(CompanySaveForm companySaveForm, 51 | @RequestParam("companyLogoFile") MultipartFile multipartFile) { 52 | Event currentEvent = eventService.getCurrentEvent(); 53 | 54 | int eventId = currentEvent.getEventId(); 55 | int companyId = companySaveForm.getCompanyId(); 56 | 57 | Company company = new Company(); 58 | company.setEventId(eventId); 59 | company.setCompanyId(companyId); 60 | company.setCompanyName(companySaveForm.getCompanyName()); 61 | company.setCompanyDetail(companySaveForm.getCompanyDetail()); 62 | 63 | companyService.saveCompany(company); 64 | 65 | if (companyId == 0 && multipartFile.getContentType() != null && multipartFile.getContentType().startsWith("image/")) { 66 | companyService.saveCompanyLogoImage(eventId, company.getCompanyId(), multipartFile); 67 | } 68 | 69 | return View.ADMIN_COMPANY_SETTING.toRedirect(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/controller/admin/EventSettingController.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.controller.admin; 2 | 3 | import com.horyu1234.eventangel.constant.View; 4 | import com.horyu1234.eventangel.domain.Event; 5 | import com.horyu1234.eventangel.factory.ModelAttributeNameFactory; 6 | import com.horyu1234.eventangel.form.EventSettingForm; 7 | import com.horyu1234.eventangel.service.EventService; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | import java.time.Instant; 15 | import java.time.LocalDateTime; 16 | import java.time.ZoneOffset; 17 | 18 | /** 19 | * Created by horyu on 2018-04-04 20 | */ 21 | @RequestMapping("/admin/eventSetting") 22 | @Controller 23 | public class EventSettingController { 24 | private EventService eventService; 25 | 26 | @Autowired 27 | public void setEventService(EventService eventService) { 28 | this.eventService = eventService; 29 | } 30 | 31 | @RequestMapping(value = "/", method = RequestMethod.GET) 32 | public String eventSetting(Model model) { 33 | Event currentEvent = eventService.getCurrentEvent(); 34 | model.addAttribute(ModelAttributeNameFactory.EVENT_ID, currentEvent.getEventId()); 35 | model.addAttribute(ModelAttributeNameFactory.EVENT_STATUS, currentEvent.getEventStatus()); 36 | model.addAttribute(ModelAttributeNameFactory.EVENT_TITLE, currentEvent.getEventTitle()); 37 | model.addAttribute(ModelAttributeNameFactory.EVENT_DETAIL, currentEvent.getEventDetail()); 38 | model.addAttribute(ModelAttributeNameFactory.EVENT_START_TIME, currentEvent.getEventStartTime().toInstant(ZoneOffset.ofHours(9)).toEpochMilli() / 1000); 39 | model.addAttribute(ModelAttributeNameFactory.EVENT_END_TIME, currentEvent.getEventEndTime().toInstant(ZoneOffset.ofHours(9)).toEpochMilli() / 1000); 40 | 41 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_EVENT_SETTING.toView()); 42 | 43 | return View.LAYOUT.getTemplateName(); 44 | } 45 | 46 | @RequestMapping(value = "/general", method = RequestMethod.POST) 47 | public String eventSettingGeneral(EventSettingForm eventSettingForm) { 48 | Event currentEvent = new Event(); 49 | currentEvent.setEventId(eventSettingForm.getEventId()); 50 | currentEvent.setEventStatus(eventSettingForm.getEventStatus()); 51 | currentEvent.setEventTitle(eventSettingForm.getEventTitle()); 52 | currentEvent.setEventDetail(eventSettingForm.getEventDetail()); 53 | currentEvent.setEventStartTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(eventSettingForm.getEventStartTime()), ZoneOffset.ofHours(9))); 54 | currentEvent.setEventEndTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(eventSettingForm.getEventEndTime()), ZoneOffset.ofHours(9))); 55 | 56 | eventService.updateEvent(currentEvent); 57 | 58 | return View.ADMIN_EVENT_SETTING.toRedirect(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.CompanySetting.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.CompanySetting=function(){var a=this;a.deletingCompanyId=0;a.init=function(){a.bindEvents()};a.bindEvents=function(){$(".companyEditBtn").click(function(c){a.startCompanyEdit($(c.target))});$(".companyDeleteBtn").click(function(c){a.startDelete($(c.target))});$("#cancelEditBtn").click(function(){a.abortCompanyEdit()});$("#deleteAbortBtn").click(function(){a.abortDelete()});$("#deleteBtn").click(function(){a.deleteConfirm()});$("#companyLogoFile").on("change",function(){var c=$(this).next(".custom-file-label"), 3 | b=$(this)[0].files;0===b.length?a.resetImageInput():(b=b[0],console.log("file changed",b),b.type.startsWith("image/")?5242880<=b.size?($("#warning-modal-text").text("\ucd5c\ub300 5MB \ubbf8\ub9cc\uc758 \ud30c\uc77c\ub9cc \uc5c5\ub85c\ub4dc\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4."),$("#warning-modal").modal(),a.resetImageInput()):(c.text(b.name),a.previewCompanyLogo(b)):($("#warning-modal-text").text("\uc774\ubbf8\uc9c0 \ud30c\uc77c\ub9cc \uc120\ud0dd\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4."), 4 | $("#warning-modal").modal(),a.resetImageInput()))})};a.resetImageInput=function(){$("#companyLogoFile").next(".custom-file-label").text("\ud68c\uc0ac \ub85c\uace0 \uc774\ubbf8\uc9c0 \ud30c\uc77c\uc744 \uc120\ud0dd\ud574\uc8fc\uc138\uc694.");$("#companyLogoPreview").attr("src","")};a.previewCompanyLogo=function(a){var b=new FileReader;b.onload=function(a){$("#companyLogoPreview").attr("src",a.target.result)};b.readAsDataURL(a)};a.startCompanyEdit=function(a){a=a.closest("tr");$("#companyId").val(a.find(".company-id").text()); 5 | $("#companyName").val(a.find(".company-name").text());$("#companyDetail").val(a.find(".company-detail").text());$(".card-header").text("\ub3c4\uc6c0\uc744 \uc8fc\uc2e0 \ud68c\uc0ac \uc218\uc815");$("#submitBtn").text("\ud68c\uc0ac \uc218\uc815");$("#cancelEditBtn").css("visibility","visible");$(".companyLogoFormInput").hide();$("html, body").animate({scrollTop:0},"fast")};a.abortCompanyEdit=function(){$("#companyId").val("0");$("#companyName").val("");$("#companyDetail").val("");$(".card-header").text("\ub3c4\uc6c0\uc744 \uc8fc\uc2e0 \ud68c\uc0ac \ucd94\uac00"); 6 | $("#submitBtn").text("\ud68c\uc0ac \ucd94\uac00");$("#cancelEditBtn").css("visibility","hidden");$(".companyLogoFormInput").show()};a.startDelete=function(c){c=c.closest("tr");a.deletingCompanyId=Number(c.find(".company-id").text());$("#delete-modal").modal({backdrop:"static",keyboard:!1})};a.abortDelete=function(){a.deletingCompanyId=0};a.deleteConfirm=function(){$("#deleteBtn").html("\ucc98\ub9ac \uc911\uc785\ub2c8\ub2e4.");$("#deleteBtn").attr("disabled","");$("#deleteAbortBtn").css("visibility", 7 | "hidden");$.ajax({type:"POST",url:"./deleteCompany",data:{companyId:a.deletingCompanyId},timeout:5E3}).done(function(){$("#deleteBtn").html("\uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.");setTimeout(function(){location.reload()},500)}).fail(function(a){$("#deleteBtn").html("\ud1b5\uc2e0\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \uc7a0\uc2dc \ud6c4 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.");setTimeout(function(){location.reload()},3E3)})};return{init:function(){a.init()}}}; 8 | //# sourceMappingURL=Horyu.View.CompanySetting.min.js.map -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/domain/Applicant.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.domain; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | /** 6 | * Created by horyu on 2018-04-03 7 | */ 8 | public class Applicant { 9 | private int eventId; 10 | private String applyEmail; 11 | private String youtubeNickname; 12 | private LocalDateTime applyTime; 13 | private String ipAddress; 14 | private String referer; 15 | private String userAgent; 16 | private String fingerprint2; 17 | private boolean duplicated; 18 | private String dupCheckAdminName; 19 | 20 | public int getEventId() { 21 | return eventId; 22 | } 23 | 24 | public void setEventId(int eventId) { 25 | this.eventId = eventId; 26 | } 27 | 28 | public LocalDateTime getApplyTime() { 29 | return applyTime; 30 | } 31 | 32 | public void setApplyTime(LocalDateTime applyTime) { 33 | this.applyTime = applyTime; 34 | } 35 | 36 | public String getApplyEmail() { 37 | return applyEmail; 38 | } 39 | 40 | public void setApplyEmail(String applyEmail) { 41 | this.applyEmail = applyEmail; 42 | } 43 | 44 | public String getYoutubeNickname() { 45 | return youtubeNickname; 46 | } 47 | 48 | public void setYoutubeNickname(String youtubeNickname) { 49 | this.youtubeNickname = youtubeNickname; 50 | } 51 | 52 | public String getIpAddress() { 53 | return ipAddress; 54 | } 55 | 56 | public void setIpAddress(String ipAddress) { 57 | this.ipAddress = ipAddress; 58 | } 59 | 60 | public String getReferer() { 61 | return referer; 62 | } 63 | 64 | public void setReferer(String referer) { 65 | this.referer = referer; 66 | } 67 | 68 | public String getUserAgent() { 69 | return userAgent; 70 | } 71 | 72 | public void setUserAgent(String userAgent) { 73 | this.userAgent = userAgent; 74 | } 75 | 76 | public String getFingerprint2() { 77 | return fingerprint2; 78 | } 79 | 80 | public void setFingerprint2(String fingerprint2) { 81 | this.fingerprint2 = fingerprint2; 82 | } 83 | 84 | public boolean isDuplicated() { 85 | return duplicated; 86 | } 87 | 88 | public void setDuplicated(boolean duplicated) { 89 | this.duplicated = duplicated; 90 | } 91 | 92 | public String getDupCheckAdminName() { 93 | return dupCheckAdminName; 94 | } 95 | 96 | public void setDupCheckAdminName(String dupCheckAdminName) { 97 | this.dupCheckAdminName = dupCheckAdminName; 98 | } 99 | 100 | public void hidePrivacy() { 101 | String email = getApplyEmail(); 102 | 103 | String originalEmailName = email.split("@")[0]; 104 | String emailName = originalEmailName.substring(0, originalEmailName.length() - 1) + "*"; 105 | String emailHost = email.split("@")[1].replaceAll("[a-zA-Z가-힣0-9\\-]", "*"); 106 | 107 | setApplyEmail(emailName + '@' + emailHost); 108 | setApplyTime(null); 109 | setIpAddress(null); 110 | setUserAgent(null); 111 | setFingerprint2(null); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.ApplicantList.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.ApplicantList=function(g){var a=this;a.options=$.extend({columnId:"",columnName:""},g);a.init=function(){a.changeMainContainerWidth();a.updateTable()};a.changeMainContainerWidth=function(){var a=$("#main-container");a.removeClass("container");a.addClass("container-full")};a.updateTable=function(){$("#loading-modal").modal({backdrop:"static",keyboard:!1});$.ajax({type:"POST",url:"./getApplicant",data:{columnId:null===a.options.columnId?void 0:a.options.columnId,columnName:null===a.options.columnName? 3 | void 0:a.options.columnName},timeout:1E4}).done(function(d){$("#loading-modal").modal("hide");Array.isArray(d)?a.updatePagination(d):($("#fail-modal").modal({backdrop:"static",keyboard:!1}),setTimeout(function(){location.reload()},4E3))})};a.updatePagination=function(d){$("#applyCount").text(d.length);$(".table-pagination").pagination({className:"paginationjs-theme-blue paginationjs-big",dataSource:d,pageSize:50,autoHidePrevious:!0,autoHideNext:!0,callback:function(c,e){a.renderTable(c)}});$(".duplicatedBtn").click(function(){var c= 4 | $(this).attr("data-apply-email");a.updateDuplicated(c,!0)});$(".notDuplicatedBtn").click(function(){var c=$(this).attr("data-apply-email");a.updateDuplicated(c,!1)})};a.renderTable=function(a){var c=$(".applicant-list-table").find("tbody");c.empty();a.forEach(function(a){var b=$("\x3ctr\x3e\x3c/tr\x3e").attr("data-apply-email",a.applyEmail);b.append($('\x3ctd class\x3d"apply-time"\x3e').html(moment(a.applyTime).format("YYYY\ub144 MMMM D\uc77c dddd\x3cbr/\x3eA h\uc2dc mm\ubd84 ss\ucd08")));b.append($('\x3ctd class\x3d"apply-email"\x3e').text(a.applyEmail)); 5 | b.append($('\x3ctd class\x3d"apply-youtubeNickname"\x3e').text(a.youtubeNickname));b.append($('\x3ctd class\x3d"apply-ipAddress"\x3e').text(a.ipAddress));b.append($('\x3ctd class\x3d"apply-referer"\x3e').text(a.referer));b.append($('\x3ctd class\x3d"apply-userAgent"\x3e').text(a.userAgent));b.append($('\x3ctd class\x3d"apply-fingerprint2"\x3e').text(a.fingerprint2));b.append($('\x3ctd class\x3d"apply-duplicated"\x3e').text(a.duplicated));a.duplicated?(b.addClass("table-warning"),b.append($("\x3ctd\x3e").html($('\x3cbutton type\x3d"button" class\x3d"btn btn-danger btn-sm notDuplicatedBtn"\x3e\uc911\ubcf5 \uc751\ubaa8 \ucc98\ub9ac \ucde8\uc18c\x3c/button\x3e').attr("data-apply-email", 6 | a.applyEmail)))):b.append($("\x3ctd\x3e").html($('\x3cbutton type\x3d"button" class\x3d"btn btn-warning btn-sm duplicatedBtn"\x3e\uc911\ubcf5 \uc751\ubaa8 \ucc98\ub9ac(\ucd94\ucca8 \uc81c\uc678)\x3c/button\x3e').attr("data-apply-email",a.applyEmail)));b.append($('\x3ctd class\x3d"apply-dupCheckAdminName"\x3e').text(a.dupCheckAdminName));c.append(b)})};a.updateDuplicated=function(a,c){$.ajax({type:"POST",url:"./changeDuplicated",data:{applyEmail:a,isDuplicated:c},timeout:1E4}).done(function(){var e= 7 | $("tr[data-apply-email\x3d'"+a+"']"),b=e.find("td:eq(8)"),f=e.find("td:eq(9)");c?(e.addClass("table-warning"),b.text("\uc911\ubcf5 \ucc98\ub9ac\ub428"),f.text("\uc911\ubcf5 \ucc98\ub9ac\ub428")):(e.removeClass("table-warning"),b.text("\uc911\ubcf5 \ucc98\ub9ac \ucde8\uc18c\ub428"),f.text("\uc911\ubcf5 \ucc98\ub9ac \ucde8\uc18c\ub428"))})};return{init:function(){a.init()}}}; 8 | //# sourceMappingURL=Horyu.View.ApplicantList.min.js.map -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/PrizeService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.horyu1234.eventangel.database.dao.CompanyDAO; 4 | import com.horyu1234.eventangel.database.dao.PrizeDAO; 5 | import com.horyu1234.eventangel.domain.Company; 6 | import com.horyu1234.eventangel.domain.CompanyAndPrize; 7 | import com.horyu1234.eventangel.domain.Prize; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.cache.annotation.CacheEvict; 10 | import org.springframework.cache.annotation.Cacheable; 11 | import org.springframework.stereotype.Service; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * Created by horyu on 2018-04-06 19 | */ 20 | @Service 21 | public class PrizeService { 22 | private CompanyDAO companyDAO; 23 | private PrizeDAO prizeDAO; 24 | 25 | @PostConstruct 26 | public void init() { 27 | prizeDAO.createTableIfNotExist(); 28 | } 29 | 30 | @Autowired 31 | public void setCompanyDAO(CompanyDAO companyDAO) { 32 | this.companyDAO = companyDAO; 33 | } 34 | 35 | @Autowired 36 | public void setPrizeDAO(PrizeDAO prizeDAO) { 37 | this.prizeDAO = prizeDAO; 38 | } 39 | 40 | @CacheEvict(value = {"prizeService.companyGiftData", "prizeService.totalPrizeAmount"}, allEntries = true) 41 | public void savePrize(Prize prize) { 42 | int eventId = prize.getEventId(); 43 | 44 | if (prize.getPrizeId() == 0) { 45 | int maxPrizeId = 0; 46 | if (!prizeDAO.getPrizeList(eventId).isEmpty()) { 47 | maxPrizeId = prizeDAO.getMaxPrizeId(eventId); 48 | } 49 | 50 | prize.setPrizeId(maxPrizeId + 1); 51 | } 52 | 53 | prizeDAO.updateOrInsertPrize(prize); 54 | } 55 | 56 | @CacheEvict(value = {"prizeService.companyGiftData", "prizeService.totalPrizeAmount"}, allEntries = true) 57 | public void deletePrize(int eventId, int prizeId) { 58 | prizeDAO.deletePrize(eventId, prizeId); 59 | } 60 | 61 | @CacheEvict(value = {"prizeService.companyGiftData", "prizeService.totalPrizeAmount"}, allEntries = true) 62 | public void deletePrizeByCompanyId(int eventId, int companyId) { 63 | prizeDAO.deletePrizeByCompanyId(eventId, companyId); 64 | } 65 | 66 | @Cacheable(value = "prizeService.companyGiftData") 67 | public List getCompanyGiftData(int eventId) { 68 | List prizeList = prizeDAO.getPrizeList(eventId); 69 | 70 | List companyAndPrizeList = new ArrayList<>(); 71 | for (Prize prize : prizeList) { 72 | Company company = companyDAO.getCompany(eventId, prize.getCompanyId()); 73 | 74 | CompanyAndPrize companyAndPrize = new CompanyAndPrize(company, prize); 75 | companyAndPrizeList.add(companyAndPrize); 76 | } 77 | 78 | return companyAndPrizeList; 79 | } 80 | 81 | @Cacheable(value = "prizeService.totalPrizeAmount") 82 | public int getTotalPrizeAmount(int eventId) { 83 | int totalAmount = 0; 84 | for (CompanyAndPrize companyAndPrize : getCompanyGiftData(eventId)) { 85 | totalAmount += companyAndPrize.getPrizeAmount(); 86 | } 87 | 88 | return totalAmount; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.PrizeSetting.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.PrizeSetting=function(g){var a=this;a.deletingPrizeId=0;a.options=$.extend({prizeList:[]},g);a.init=function(){a.updateTable();a.bindEvents()};a.bindEvents=function(){$(".prizeEditBtn").click(function(b){a.startPrizeEdit($(b.target))});$(".prizeDeleteBtn").click(function(b){a.startDelete($(b.target))});$("#cancelEditBtn").click(function(){a.abortPrizeEdit()});$("#deleteAbortBtn").click(function(){a.abortDelete()});$("#deleteBtn").click(function(){a.deleteConfirm()})};a.startPrizeEdit=function(a){a= 3 | a.closest("tr");$("#prizeId").val(a.find(".prize-name").attr("data-prize-id"));$("#companyId").val(a.find(".prize-name").attr("data-company-id"));$("#prizeName").val(a.find(".prize-name").text());$("#prizeAmount").val(a.find(".prize-amount").text());$(".card-header").text("\uc0c1\ud488 \uc218\uc815");$("#submitBtn").text("\uc0c1\ud488 \uc218\uc815");$("#cancelEditBtn").css("visibility","visible");$("html, body").animate({scrollTop:0},"fast")};a.abortPrizeEdit=function(){$("#prizeId").val("0");$("#prizeName").val(""); 4 | $("#prizeAmount").val("");$(".card-header").text("\uc0c1\ud488 \ucd94\uac00");$("#submitBtn").text("\uc0c1\ud488 \ucd94\uac00");$("#cancelEditBtn").css("visibility","hidden")};a.startDelete=function(b){b=b.closest("tr");a.deletingPrizeId=Number(b.find(".prize-name").attr("data-prize-id"));$("#delete-modal").modal({backdrop:"static",keyboard:!1})};a.abortDelete=function(){a.deletingPrizeId=0};a.deleteConfirm=function(){$("#deleteBtn").html("\ucc98\ub9ac \uc911\uc785\ub2c8\ub2e4.");$("#deleteBtn").attr("disabled", 5 | "");$("#deleteAbortBtn").css("visibility","hidden");$.ajax({type:"POST",url:"./deletePrize",data:{prizeId:a.deletingPrizeId},timeout:5E3}).done(function(){$("#deleteBtn").html("\uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.");setTimeout(function(){location.reload()},500)}).fail(function(a){$("#deleteBtn").html("\ud1b5\uc2e0\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \uc7a0\uc2dc \ud6c4 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694.");setTimeout(function(){location.reload()},3E3)})};a.updateTable= 6 | function(){var b=$("#prize-table tbody");b.empty();var d=a.options.prizeList.groupBy("companyId");Object.forEach(d,function(c){c=c.sortBy("prizeId");var d=0;Object.forEach(c,function(f){var e=$("\x3ctr\x3e");0===d&&e.append(a.makeCompanyCell(c.length,f));e.append($('\x3ctd class\x3d"prize-name"\x3e').attr("data-prize-id",f.prizeId).attr("data-company-id",f.companyId).text(f.prizeName));e.append($('\x3ctd class\x3d"prize-amount"\x3e').text(f.prizeAmount));e.append($('\x3ctd\x3e\x3cbutton type\x3d"button" class\x3d"btn btn-info btn-sm prizeEditBtn"\x3e\uc218\uc815\x3c/button\x3e\x3c/td\x3e')); 7 | e.append($('\x3ctd\x3e\x3cbutton type\x3d"button" class\x3d"btn btn-danger btn-sm prizeDeleteBtn"\x3e\uc0ad\uc81c\x3c/button\x3e\x3c/td\x3e'));b.append(e);d++})})};a.makeCompanyCell=function(a,d){var c=$('\x3ctd class\x3d"company-cell"\x3e').attr("rowspan",a),g=$('\x3cimg class\x3d"company-logo" src\x3d"/companyLogo?companyId\x3d'+d.companyId+'"/\x3e'),f=$('\x3ca style\x3d"font-size: 16pt;font-weight: bold;"\x3e'+d.companyName+"\x3c/a\x3e"),e=$('\x3ca style\x3d"color: gray"\x3e'+d.companyDetail+"\x3c/a\x3e"); 8 | null!==d.companyLogoImageFileName?c.append(g):c.append(f);c.append("\x3cbr/\x3e");c.append(e);return c};return{init:function(){a.init()}}}; 9 | //# sourceMappingURL=Horyu.View.PrizeSetting.min.js.map -------------------------------------------------------------------------------- /src/main/resources/static/js/component/Horyu.View.CompanyGiftTable.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.CompanyGiftTable=function(m){var h=$("#company-gift-table"),g=h.find("tbody"),n=h.find("thead"),a=this;a.companyGiftData=[];a.currentEventWinnerData=[];a.nextLotteryGift=null;a.options=$.extend({includeEventWinner:!0},m);a.init=function(){a.updateTableHeaders()};a.updateTableHeaders=function(){var b=n.find("tr");b.append("\x3cth\x3e\ub3c4\uc6c0\uc744 \uc8fc\uc2e0 \ud68c\uc0ac\x3c/th\x3e");b.append("\x3cth\x3e\uc0c1\ud488\x3c/th\x3e");a.options.includeEventWinner?(b.append('\x3cth width\x3d"250px"\x3e\ub2f9\ucca8\uc790 \uc774\uba54\uc77c\x3c/th\x3e'), 3 | b.append('\x3cth width\x3d"250px"\x3e\ub2f9\ucca8\uc790 \uc720\ud29c\ube0c \ub2c9\ub124\uc784\x3c/th\x3e')):b.append('\x3cth width\x3d"100px"\x3e\uc0c1\ud488 \uac1c\uc218\x3c/th\x3e')};a.updateTable=function(){a.nextLotteryGift=null;g.empty();var b=a.companyGiftData.groupBy("companyId");Object.keys(b).forEach(function(c){var d=b[c],d=d.sortBy("prizeId"),f=0;d.forEach(function(b){var d=b.prizeAmount;if(a.options.includeEventWinner)for(var k=0;k notDupApplyCount) { 61 | canStartLottery = false; 62 | cantStartMessage = "존재하는 상품의 수보다 응모 신청을 한 사람의 수가 적습니다."; 63 | } 64 | 65 | model.addAttribute("cantApply", eventDetailStatus == EventDetailStatus.ALREADY_END || eventDetailStatus == EventDetailStatus.CLOSE); 66 | 67 | model.addAttribute("canStartLottery", canStartLottery); 68 | model.addAttribute("cantStartMessage", cantStartMessage); 69 | 70 | model.addAttribute("notDupApplyCount", notDupApplyCount); 71 | model.addAttribute("dupApplyCount", dupApplyCount); 72 | 73 | List winnerList = eventWinnerService.getWinnerList(currentEvent.getEventId()); 74 | winnerList = eventWinnerService.hidePrivacy(winnerList); 75 | 76 | model.addAttribute("companyGiftData", prizeService.getCompanyGiftData(currentEvent.getEventId())); 77 | model.addAttribute("eventWinnerData", winnerList); 78 | 79 | model.addAttribute(ModelAttributeNameFactory.VIEW_NAME, View.ADMIN_LOTTERY.toView()); 80 | 81 | return View.LAYOUT.getTemplateName(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/database/dao/CompanyDAO.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.database.dao; 2 | 3 | import com.horyu1234.eventangel.database.mapper.CompanyMapper; 4 | import com.horyu1234.eventangel.domain.Company; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | @Repository 12 | public class CompanyDAO { 13 | private JdbcTemplate jdbcTemplate; 14 | private CompanyMapper companyMapper; 15 | 16 | @Autowired 17 | public CompanyDAO(JdbcTemplate jdbcTemplate, CompanyMapper companyMapper) { 18 | this.jdbcTemplate = jdbcTemplate; 19 | this.companyMapper = companyMapper; 20 | } 21 | 22 | public void createTableIfNotExist() { 23 | jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS `COMPANY` ( " + 24 | "`EVENT_ID` INT(11) NOT NULL, " + 25 | "`COMPANY_ID` INT(11) NOT NULL, " + 26 | "`COMPANY_NAME` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 27 | "`COMPANY_DETAIL` TEXT NOT NULL COLLATE 'utf8mb4_unicode_ci', " + 28 | "`COMP_LOGO_IMG_FNAME` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci', " + 29 | "PRIMARY KEY (`EVENT_ID`, `COMPANY_ID`) " + 30 | ") " + 31 | "COLLATE='utf8mb4_unicode_ci' " + 32 | "ENGINE=InnoDB;"); 33 | } 34 | 35 | public Company getCompany(int eventId, int companyId) { 36 | return jdbcTemplate.queryForObject( 37 | "SELECT * FROM `COMPANY` " + 38 | "WHERE EVENT_ID = ? AND COMPANY_ID = ? " + 39 | "ORDER BY `COMPANY_ID` " + 40 | "DESC;", 41 | new Object[]{eventId, companyId}, 42 | companyMapper); 43 | } 44 | 45 | public List getCompanyList(int eventId) { 46 | return jdbcTemplate.query( 47 | "SELECT * FROM `COMPANY` " + 48 | "WHERE EVENT_ID = ? " + 49 | "ORDER BY `COMPANY_ID` " + 50 | "ASC;", 51 | new Object[]{eventId}, 52 | companyMapper); 53 | } 54 | 55 | public int getMaxCompanyId(int eventId) { 56 | return jdbcTemplate.queryForObject( 57 | "SELECT MAX(COMPANY_ID) " + 58 | "FROM `COMPANY` " + 59 | "WHERE EVENT_ID = ?;", 60 | new Object[]{eventId}, 61 | Integer.class); 62 | } 63 | 64 | public void updateOrInsertCompany(Company company) { 65 | jdbcTemplate.update("INSERT INTO `COMPANY` (EVENT_ID, COMPANY_ID, COMPANY_NAME, COMPANY_DETAIL) VALUES (?, ?, ?, ?) " + 66 | "ON DUPLICATE KEY UPDATE COMPANY_ID = ?, COMPANY_NAME = ?, COMPANY_DETAIL = ?;", 67 | company.getEventId(), company.getCompanyId(), company.getCompanyName(), company.getCompanyDetail(), 68 | company.getCompanyId(), company.getCompanyName(), company.getCompanyDetail()); 69 | } 70 | 71 | public void updateCompanyLogo(int eventId, int companyId, String fileName) { 72 | jdbcTemplate.update("UPDATE `COMPANY` " + 73 | "SET COMP_LOGO_IMG_FNAME = ? " + 74 | "WHERE EVENT_ID = ? AND COMPANY_ID = ?", 75 | fileName, eventId, companyId); 76 | } 77 | 78 | public void deleteCompany(int eventId, int companyId) { 79 | jdbcTemplate.update("DELETE FROM `COMPANY` " + 80 | "WHERE EVENT_ID = ? AND COMPANY_ID = ?", 81 | eventId, companyId); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/countUp-1.9.3/countUp.min.js: -------------------------------------------------------------------------------- 1 | !function(a,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n(require,exports,module):a.CountUp=n()}(this,function(a,n,t){var e=function(a,n,t,e,i,r){function o(a){var n,t,e,i,r,o,s=a<0;if(a=Math.abs(a).toFixed(l.decimals),a+="",n=a.split("."),t=n[0],e=n.length>1?l.options.decimal+n[1]:"",l.options.useGrouping){for(i="",r=0,o=t.length;rl.endVal,l.frameVal=l.startVal,l.initialized=!0,!0):(l.error="[CountUp] startVal ("+n+") or endVal ("+t+") is not a number",!1)):(l.error="[CountUp] target is null or undefined",!1))},l.printValue=function(a){var n=l.options.formattingFn(a);"INPUT"===l.d.tagName?this.d.value=n:"text"===l.d.tagName||"tspan"===l.d.tagName?this.d.textContent=n:this.d.innerHTML=n},l.count=function(a){l.startTime||(l.startTime=a),l.timestamp=a;var n=a-l.startTime;l.remaining=l.duration-n,l.options.useEasing?l.countDown?l.frameVal=l.startVal-l.options.easingFn(n,0,l.startVal-l.endVal,l.duration):l.frameVal=l.options.easingFn(n,l.startVal,l.endVal-l.startVal,l.duration):l.countDown?l.frameVal=l.startVal-(l.startVal-l.endVal)*(n/l.duration):l.frameVal=l.startVal+(l.endVal-l.startVal)*(n/l.duration),l.countDown?l.frameVal=l.frameVall.endVal?l.endVal:l.frameVal,l.frameVal=Math.round(l.frameVal*l.dec)/l.dec,l.printValue(l.frameVal),nl.endVal,l.rAF=requestAnimationFrame(l.count))}},l.initialize()&&l.printValue(l.startVal)};return e}); -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.Lottery.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.Lottery=function(g){var a=this;a.companyGiftTable=null;a.currentEventWinnerData=[];a.options=$.extend({notDupApplyCount:0,dupApplyCount:0,companyGiftData:[],eventWinnerData:[]},g);a.init=function(){a.companyGiftTable=new Horyu.View.CompanyGiftTable;a.companyGiftTable.init();a.updateTable();a.bindEvents();setInterval(function(){$("#currentTime").text(moment().format("YYYY\ub144 MMMM D\uc77c dddd A h\uc2dc mm\ubd84 ss\ucd08"))},500);var b={useEasing:!0,useGrouping:!0,separator:",",decimal:"."}, 3 | c=new CountUp("notDupApplyCount",0,a.options.notDupApplyCount,0,3,b);c.error?console.error(c.error):c.start();b=new CountUp("dupApplyCount",0,a.options.dupApplyCount,0,3,b);b.error?console.error(b.error):b.start()};a.updateTable=function(){a.companyGiftTable.updateTable(a.options.companyGiftData,a.options.eventWinnerData);var b=$(".next-gift-alert"),c=$(".next-gift-name"),d=$(".lotteryBtn"),e=a.companyGiftTable.getNextLotteryGift();null===e?(b.remove(),d.attr("disabled",""),d.html('\x3ci class\x3d"fas fa-random"\x3e\x3c/i\x3e\x26nbsp; [\ucd94\ucca8 \ubd88\uac00] \ubaa8\ub4e0 \uc0c1\ud488 \ucd94\ucca8\uc774 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.')): 4 | (c.text(e.prizeName),d.html('\x3ci class\x3d"fas fa-random"\x3e\x3c/i\x3e\x26nbsp; \ub2e4\uc74c \uc0c1\ud488 \ucd94\ucca8\ud558\uae30'))};a.bindEvents=function(){$(".lotteryBtn").click(function(){if(a.isIE())$("#ie-modal").modal({backdrop:"static",keyboard:!1});else{$(".lotteryBtn").attr("disabled","");$(".lotteryBtn").html('\x3ci class\x3d"fas fa-spinner fa-pulse"\x3e\x3c/i\x3e\x26nbsp; \ucd94\ucca8 \uc911\uc785\ub2c8\ub2e4...');var b=moment();$.ajax({type:"POST",url:"./lottery",data:{prizeId:a.companyGiftTable.getNextLotteryGift().prizeId}, 5 | timeout:12E4}).done(function(c){if("object"!==typeof c)$(".lotteryBtn").html('\x3ci class\x3d"fas fa-exclamation-triangle"\x3e\x3c/i\x3e\x26nbsp; \ucd94\ucca8\uc5d0 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.'),$(".lotteryBtn").removeClass("btn-success"),$(".lotteryBtn").addClass("btn-danger"),setTimeout(function(){location.reload()},4E3);else{var d=moment();5E3<=moment.duration(d.diff(b)).valueOf()?a.lotteryOut(c):setTimeout(function(){a.lotteryOut(c)},Math.round(3E3*Math.random())+3E3)}}).fail(function(a){$(".lotteryBtn").html('\x3ci class\x3d"fas fa-exclamation-triangle"\x3e\x3c/i\x3e\x26nbsp; \ucd94\ucca8\uc5d0 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4.'); 6 | $(".lotteryBtn").removeClass("btn-success");$(".lotteryBtn").addClass("btn-danger");setTimeout(function(){location.reload()},4E3)})}});new ClipboardJS(".btn-copy");$(".btn-copy").click(function(){var b=a.companyGiftTable.getNextLotteryGift(),c=b.prizeId,b=b.prizeName,d=$("#modal-youtubeNickname").text(),e=$("#modal-email").text(),f=$(".btn-copy");f.attr("data-clipboard-text",c+". "+b+"\n"+d+" "+e+"\n\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\x3d\n"); 7 | f.attr("disabled","");f.text("\ubcf5\uc0ac \uc644\ub8cc!")})};a.lotteryOut=function(b){$(".lotteryBtn").html("\uc5f4\ub9b0 \ucc3d\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694.");var c=a.companyGiftTable.getNextLotteryGift(),d=$("#modal-company-logo");null!==c.companyLogoImageFileName?(d.show(),d.attr("src","/companyLogo?companyId\x3d"+c.companyId)):d.hide();$("#modal-companyName").text(c.companyName);$("#modal-companyDetail").text(c.companyDetail);$("#modal-prizeName").text(c.prizeName);$("#modal-youtubeNickname").text(b.youtubeNickname); 8 | $("#modal-email").text(b.applyEmail);$("#lottery-modal").modal({backdrop:"static",keyboard:!1})};a.isIE=function(){var a=window.navigator.userAgent.toLowerCase();return"netscape"===navigator.appName.toLowerCase()&&-1!==a.search("trident")||-1!==a.indexOf("msie")?!0:!1};return{init:function(){a.init()}}}; 9 | //# sourceMappingURL=Horyu.View.Lottery.min.js.map -------------------------------------------------------------------------------- /src/main/resources/static/js/admin/Horyu.View.EventSetting.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"Horyu.View.EventSetting.min.js", 4 | "lineCount":7, 5 | "mappings":"AAEA,IAAIA,MAAQC,MAAAD,MAARA,EAAwB,EAC5BA,MAAAE,KAAA,CAAaD,MAAAD,MAAAE,KAAb,EAAkC,EAClCF;KAAAE,KAAAC,aAAA,CAA0BC,QAAQ,CAACC,CAAD,CAAU,CACxC,IAAIC,EAAQ,IAOZA,EAAAD,QAAA,CAAgBE,CAAAC,OAAA,CALKC,CACjBC,eAAgB,CADCD,CAEjBE,aAAc,CAFGF,CAKL,CAAyBJ,CAAzB,CAEhBC,EAAAM,KAAA,CAAaC,QAAQ,EAAG,CACpBP,CAAAQ,oBAAA,EACAR,EAAAS,WAAA,EAEAT,EAAAU,oBAAA,CAAwD,MAAxD,GAA0BV,CAAAW,kBAAA,EAA1B,CAJoB,CAOxBX,EAAAQ,oBAAA,CAA4BI,QAAQ,EAAG,CACnCX,CAAA,CAAE,YAAF,CAAAY,gBAAA,CAAgC,CAC5BC,WAAY,CAAA,CADgB,CAE5BC,oBAAqB,CAFO,CAG5BC,kBAAmB,CAAA,CAHS,CAI5BC,cAAe,CAAA,CAJa,CAK5BC,eAAgB,CAAA,CALY,CAM5BC,UAAWC,MAAAC,KAAA,CAAYrB,CAAAD,QAAAK,eAAZ,CANiB,CAO5BkB,QAASF,MAAAC,KAAA,CAAYrB,CAAAD,QAAAM,aAAZ,CAPmB,CAQ5BkB,UAAW,CACPC,KAAM,CADC,CARiB,CAW5BC,OAAQ,CACJC,OAAQ,0DADJ;AAEJC,WAAY,cAFR,CAGJC,YAAa,cAHT,CAIJC,WAAY,4CAAA,MAAA,CAAA,EAAA,CAJR,CAOJC,WAAY,oGAAA,MAAA,CAAA,GAAA,CAPR,CAXoB,CAAhC,CADmC,CA0BvC9B,EAAAS,WAAA,CAAmBsB,QAAQ,EAAG,CAC1B9B,CAAA,CAAE,oBAAF,CAAA+B,OAAA,CAA+B,QAAQ,EAAG,CACtChC,CAAAU,oBAAA,CAAiD,MAAjD,GAA0BT,CAAA,CAAE,IAAF,CAAAgC,KAAA,CAAa,IAAb,CAA1B,CADsC,CAA1C,CAIAhC,EAAA,CAAE,YAAF,CAAAiC,MAAA,CAAsB,QAAQ,EAAG,CAC7B,IAAIrB,EAAkBZ,CAAA,CAAE,YAAF,CAAAkC,KAAA,CAAqB,iBAArB,CAEtBlC,EAAA,CAAE,cAAF,CAAAmC,IAAA,CAAsBpC,CAAAW,kBAAA,EAAtB,CACAV,EAAA,CAAE,iBAAF,CAAAmC,IAAA,CAAyBvB,CAAAM,UAAAE,KAAA,EAAzB,CACApB;CAAA,CAAE,eAAF,CAAAmC,IAAA,CAAuBvB,CAAAS,QAAAD,KAAA,EAAvB,CAEApB,EAAA,CAAE,mBAAF,CAAAoC,OAAA,EAP6B,CAAjC,CAUApC,EAAA,CAAE,cAAF,CAAAiC,MAAA,CAAwB,QAAQ,EAAG,CAC/BjC,CAAA,CAAE,kBAAF,CAAAqC,MAAA,CAA4B,CACxBC,SAAU,QADc,CAExBC,SAAU,CAAA,CAFc,CAA5B,CAD+B,CAAnC,CAOAvC,EAAA,CAAE,qBAAF,CAAAiC,MAAA,CAA+B,QAAQ,EAAG,CACtCjC,CAAA,CAAE,qBAAF,CAAAwC,KAAA,CAA8B,wCAA9B,CACAxC,EAAA,CAAE,qBAAF,CAAAgC,KAAA,CAA8B,UAA9B,CAA0C,EAA1C,CACAhC,EAAA,CAAE,WAAF,CAAAyC,IAAA,CAAmB,YAAnB,CAAiC,QAAjC,CAEAzC,EAAA0C,KAAA,CAAO,CACHC,KAAM,KADH,CAEHC,IAAK,YAFF,CAGHC,QAAS,GAHN,CAAP,CAAAC,KAAA,CAIQ,QAAQ,EAAG,CACf9C,CAAA,CAAE,qBAAF,CAAAwC,KAAA,CAA8B,6CAA9B,CACAO;UAAA,CAAW,QAAQ,EAAG,CAClBC,QAAAC,OAAA,EADkB,CAAtB,CAEG,GAFH,CAFe,CAJnB,CAAAC,KAAA,CASQ,QAAQ,CAACC,CAAD,CAAM,CAClBnD,CAAA,CAAE,qBAAF,CAAAwC,KAAA,CAA8B,iIAA9B,CACAO,WAAA,CAAW,QAAQ,EAAG,CAClBC,QAAAC,OAAA,EADkB,CAAtB,CAEG,GAFH,CAFkB,CATtB,CALsC,CAA1C,CAsBAjD,EAAA,CAAE,mBAAF,CAAAiC,MAAA,CAA6B,QAAQ,EAAG,CACpCjC,CAAA,CAAE,2BAAF,CAAAqC,MAAA,CAAqC,CACjCC,SAAU,QADuB,CAEjCC,SAAU,CAAA,CAFuB,CAArC,CADoC,CAAxC,CAOAvC,EAAA,CAAE,6BAAF,CAAAiC,MAAA,CAAuC,QAAQ,EAAG,CAC9CjC,CAAA,CAAE,6BAAF,CAAAwC,KAAA,CAAsC,wCAAtC,CACAxC;CAAA,CAAE,6BAAF,CAAAgC,KAAA,CAAsC,UAAtC,CAAkD,EAAlD,CACAhC,EAAA,CAAE,WAAF,CAAAyC,IAAA,CAAmB,YAAnB,CAAiC,QAAjC,CAEAzC,EAAA0C,KAAA,CAAO,CACHC,KAAM,KADH,CAEHC,IAAK,oBAFF,CAGHC,QAAS,GAHN,CAAP,CAAAC,KAAA,CAIQ,QAAQ,EAAG,CACf9C,CAAA,CAAE,6BAAF,CAAAwC,KAAA,CAAsC,6CAAtC,CACAO,WAAA,CAAW,QAAQ,EAAG,CAClBC,QAAAC,OAAA,EADkB,CAAtB,CAEG,GAFH,CAFe,CAJnB,CAAAC,KAAA,CASQ,QAAQ,CAACC,CAAD,CAAM,CAClBnD,CAAA,CAAE,6BAAF,CAAAwC,KAAA,CAAsC,iIAAtC,CACAO,WAAA,CAAW,QAAQ,EAAG,CAClBC,QAAAC,OAAA,EADkB,CAAtB;AAEG,GAFH,CAFkB,CATtB,CAL8C,CAAlD,CAnD0B,CA0E9BlD,EAAAW,kBAAA,CAA0B0C,QAAQ,EAAG,CACjC,MAAOpD,EAAA,CAAE,oCAAF,CAAAgC,KAAA,CAA6C,IAA7C,CAD0B,CAIrCjC,EAAAU,oBAAA,CAA4B4C,QAAQ,CAACC,CAAD,CAAW,CACvCA,CAAJ,CACItD,CAAA,CAAE,wBAAF,CAAAuD,KAAA,CAAiC,GAAjC,CADJ,CAGIvD,CAAA,CAAE,wBAAF,CAAAwD,KAAA,CAAiC,GAAjC,CAJuC,CAQ/C,OAAO,CACHnD,KAAMA,QAAQ,EAAG,CACbN,CAAAM,KAAA,EADa,CADd,CAjIiC;", 6 | "sources":["/js/admin/Horyu.View.EventSetting.js"], 7 | "names":["Horyu","window","View","EventSetting","Horyu.View.EventSetting","options","_this","$","extend","defaultOptions","eventStartTime","eventEndTime","init","_this.init","initDateRangePicker","bindEvents","updateVisibleStatus","getOpenEventBtnId","_this.initDateRangePicker","daterangepicker","timePicker","timePickerIncrement","timePickerSeconds","showDropdowns","todayHighlight","startDate","moment","unix","endDate","dateLimit","year","locale","format","applyLabel","cancelLabel","daysOfWeek","monthNames","_this.bindEvents","change","attr","click","data","val","submit","modal","backdrop","keyboard","html","css","ajax","type","url","timeout","done","setTimeout","location","reload","fail","msg","_this.getOpenEventBtnId","_this.updateVisibleStatus","isActive","show","hide"] 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/static/js/Horyu.View.Apply.min.js: -------------------------------------------------------------------------------- 1 | var Horyu=window.Horyu||{};Horyu.View=window.Horyu.View||{}; 2 | Horyu.View.Apply=function(d){var a=this;a.companyGiftTable=null;a.options=$.extend({applyCount:0,eventStatus:"CLOSE",eventStartTime:0,eventEndTime:0,companyGiftData:[],eventWinnerData:[]},d);a.init=function(){a.initFingerprint2();a.initParsley();a.updateAlertBanner();a.bindEvents()};a.initFingerprint2=function(){(new Fingerprint2({excludeWebGL:!0})).get(function(a){$("#fingerprint2").val(a)})};a.initParsley=function(){$("#applyForm").parsley({successClass:"is-valid",errorClass:"is-invalid",classHandler:function(a){return a.$element.closest("input")}})}; 3 | a.updateAlertBanner=function(){var c=$(".alert-banner");if("START_SOON"===a.options.eventStatus)c.html('\x3ca style\x3d"font-weight: bold; font-size: 20pt;"\x3e\ub2e4\uc74c \uc2dc\uac04 \uc774\ud6c4\uc5d0 \uc751\ubaa8\uac00 \uac00\ub2a5\ud569\ub2c8\ub2e4.\x3c/a\x3e\x3cbr/\x3e\x3ca id\x3d"time-countdown" style\x3d"font-weight: bold; font-size: 32pt;"\x3e\x3c/a\x3e'),$("#time-countdown").countdown(moment.unix(a.options.eventStartTime).toDate()).on("update.countdown",function(a){$(this).html(a.strftime("%D\uc77c %H\uc2dc\uac04 %M\ubd84 %S\ucd08"))}).on("finish.countdown", 4 | function(a){$(".alert-banner").html('\x3ca style\x3d"font-weight: bold; font-size: 20pt;"\x3e\ud398\uc774\uc9c0\uac00 \uc790\ub3d9 \uc0c8\ub85c\uace0\uce68\ub429\ub2c8\ub2e4.\x3cbr/\x3e\uc0c8\ub85c\uace0\uce68\uc774 \uc548\ub420 \uacbd\uc6b0, \uc9c1\uc811 \uc0c8\ub85c\uace0\uce68 \ubc84\ud2bc\uc744 \ub20c\ub7ec\uc8fc\uc138\uc694.\x3c/a\x3e');window.location.reload()});else if("ALREADY_END"===a.options.eventStatus){var b={useEasing:!0,useGrouping:!0,separator:",",decimal:".",suffix:"\uba85"},b=new CountUp("applyCount", 5 | 0,a.options.applyCount,0,5,b);b.error?console.error(b.error):b.start();c.html('\x3ca style\x3d"font-weight: bold; font-size: 20pt;"\x3e\ub2e4\uc74c \uc2dc\uac04 \uc804\uc5d0 \uc774\ubbf8 \uc751\ubaa8 \uc2e0\uccad\uc774 \ub9c8\uac10\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\x3c/a\x3e\x3cbr/\x3e\x3ca id\x3d"time-countdown" style\x3d"font-weight: bold; font-size: 32pt;"\x3e\x3c/a\x3e');c=moment.unix(a.options.eventEndTime).subtract(new Date);$("#time-countdown").countdown(c.toDate(),{elapse:!0}).on("update.countdown", 6 | function(a){$(this).html(a.strftime("%D\uc77c %H\uc2dc\uac04 %M\ubd84 %S\ucd08"))})}else"OPEN"===a.options.eventStatus?(c.html('\x3ca style\x3d"font-size: 12pt;"\x3e\x3ca id\x3d"time-countdown" style\x3d"font-weight: bold;"\x3e\x3c/a\x3e \uc774\ud6c4 \uc751\ubaa8 \uc2e0\uccad\uc774 \ub9c8\uac10\ub429\ub2c8\ub2e4.\x3c/a\x3e'),b={useEasing:!0,useGrouping:!0,separator:",",decimal:".",suffix:"\uba85"},b=new CountUp("applyCount",0,a.options.applyCount,0,3,b),b.error?console.error(b.error):b.start(),$("#time-countdown").countdown(moment.unix(a.options.eventEndTime).toDate()).on("update.countdown", 7 | function(a){$(this).html(a.strftime("%D\uc77c %H\uc2dc\uac04 %M\ubd84 %S\ucd08"))}).on("finish.countdown",function(a){$(".alert-banner").html('\x3ca style\x3d"font-weight: bold; font-size: 20pt;"\x3e\uc751\ubaa8 \uc2e0\uccad\uc774 \ub9c8\uac10\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\x3c/a\x3e');window.location.reload()}),a.companyGiftTable=new Horyu.View.CompanyGiftTable({includeEventWinner:!1}),a.companyGiftTable.init(),a.companyGiftTable.updateTable(a.options.companyGiftData,a.options.eventWinnerData)): 8 | "CLOSE"===a.options.eventStatus?c.text("\ud604\uc7ac \uc751\ubaa8 \uc2e0\uccad\uc744 \ubc1b\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4."):"LOTTERY"===a.options.eventStatus&&(c.html("\uc544\ub798\uc5d0\uc11c \ud604\uc7ac \uc774\ubca4\ud2b8 \ub2f9\ucca8\uc790 \ubaa9\ub85d\uc744 \ud655\uc778\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4."),c.removeClass("alert-warning"),c.addClass("alert-success"),a.companyGiftTable=new Horyu.View.CompanyGiftTable,a.companyGiftTable.init(),a.companyGiftTable.updateTable(a.options.companyGiftData, 9 | a.options.eventWinnerData))};a.bindEvents=function(){$(".submitBtn").click(function(){$("#applyForm").parsley().validate()&&grecaptcha.execute()});$(".notSubscriberBtn").click(function(){$("#submit-modal").modal()})};return{init:function(){a.init()}}};function onReCaptchaCallback(){$("#applyForm").submit()}; 10 | //# sourceMappingURL=Horyu.View.Apply.min.js.map -------------------------------------------------------------------------------- /src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | 77 | -------------------------------------------------------------------------------- /src/main/java/com/horyu1234/eventangel/service/CompanyService.java: -------------------------------------------------------------------------------- 1 | package com.horyu1234.eventangel.service; 2 | 3 | import com.horyu1234.eventangel.database.dao.CompanyDAO; 4 | import com.horyu1234.eventangel.domain.Company; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.web.multipart.MultipartFile; 11 | 12 | import javax.annotation.PostConstruct; 13 | import java.io.File; 14 | import java.io.FileOutputStream; 15 | import java.io.IOException; 16 | import java.util.List; 17 | import java.util.UUID; 18 | 19 | /** 20 | * Created by horyu on 2018-04-06 21 | */ 22 | @Service 23 | public class CompanyService { 24 | private static final Logger LOGGER = LoggerFactory.getLogger(CompanyService.class); 25 | private CompanyDAO companyDAO; 26 | 27 | @Value("${spring.upload-dir.company-logo-image}") 28 | private String companyLogoImageUploadDir; 29 | 30 | @PostConstruct 31 | public void init() { 32 | companyDAO.createTableIfNotExist(); 33 | } 34 | 35 | @Autowired 36 | public void setCompanyDAO(CompanyDAO companyDAO) { 37 | this.companyDAO = companyDAO; 38 | } 39 | 40 | public void saveCompany(Company company) { 41 | int eventId = company.getEventId(); 42 | 43 | if (company.getCompanyId() == 0) { 44 | int maxCompanyId = 0; 45 | 46 | if (!companyDAO.getCompanyList(eventId).isEmpty()) { 47 | maxCompanyId = companyDAO.getMaxCompanyId(eventId); 48 | } 49 | 50 | company.setCompanyId(maxCompanyId + 1); 51 | } 52 | 53 | companyDAO.updateOrInsertCompany(company); 54 | } 55 | 56 | public void saveCompanyLogoImage(int eventId, int companyId, MultipartFile multipartFile) { 57 | File uploadDir = new File(companyLogoImageUploadDir); 58 | if (!uploadDir.exists()) { 59 | uploadDir.mkdirs(); 60 | } 61 | 62 | String originalFilename = multipartFile.getOriginalFilename(); 63 | 64 | String extension = originalFilename.split("\\.")[1]; 65 | String randomUUID = UUID.randomUUID().toString(); 66 | 67 | String fileName = randomUUID + "." + extension; 68 | 69 | File file = new File(companyLogoImageUploadDir, fileName); 70 | 71 | try { 72 | file.createNewFile(); 73 | } catch (IOException e) { 74 | LOGGER.error("업로드한 회사 로고 이미지 파일을 생성하는 중 오류가 발생하였습니다.", e); 75 | } 76 | 77 | try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { 78 | fileOutputStream.write(multipartFile.getBytes()); 79 | } catch (IOException e) { 80 | LOGGER.error("업로드한 회사 로고 이미지파일을 기록하는 중 오류가 발생하였습니다.", e); 81 | } 82 | 83 | companyDAO.updateCompanyLogo(eventId, companyId, fileName); 84 | } 85 | 86 | public void deleteCompany(int eventId, int companyId) { 87 | companyDAO.deleteCompany(eventId, companyId); 88 | } 89 | 90 | public void deleteCompanyLogoImage(int eventId, int companyId) { 91 | File companyLogoImage = getCompanyLogoImage(eventId, companyId); 92 | if (companyLogoImage == null) { 93 | return; 94 | } 95 | 96 | if (companyLogoImage.exists()) { 97 | companyLogoImage.delete(); 98 | } 99 | } 100 | 101 | public List getCompanyList(int eventId) { 102 | return companyDAO.getCompanyList(eventId); 103 | } 104 | 105 | public Company getCompany(int eventId, int companyId) { 106 | return companyDAO.getCompany(eventId, companyId); 107 | } 108 | 109 | public File getCompanyLogoImage(int eventId, int companyId) { 110 | Company company = getCompany(eventId, companyId); 111 | 112 | String companyLogoImageFileName = company.getCompanyLogoImageFileName(); 113 | if (companyLogoImageFileName == null) { 114 | return null; 115 | } 116 | 117 | return new File(companyLogoImageUploadDir, companyLogoImageFileName); 118 | } 119 | } 120 | --------------------------------------------------------------------------------