- 시스템관리 > 관리자목록조회, 관리자등록, 관리자수정, 관리자삭제, 관리자상세조회

This commit is contained in:
kimre
2022-05-29 10:12:37 +09:00
parent ad80b88089
commit 5077696e46
275 changed files with 17338 additions and 23433 deletions

View File

@@ -1,3 +1,3 @@
<template>
<router-view/>
</template>
<template>
<router-view/>
</template>

View File

@@ -31,6 +31,7 @@ footer,header,hgroup,menu,nav,section {
display:block;
}
table {
font-family: 'SpoqaHanSansNeo';
border-collapse:collapse;
border:0 none;
}
@@ -38,16 +39,28 @@ input, select, option{
font-family: 'SpoqaHanSansNeo';
}
input:focus{
outline: 1px solid #000;
border: 1px solid #000 !important;
}
input:focus + label{
color:#000;
}
input:valid + label{
color:#000;
}
select:focus{
outline: 1px solid #000;
border: 1px solid #000 !important;
}
input[type="checkbox"] + label{
cursor: pointer;
}
input:disabled{
background-color: #eeeeee;
background-color: #eeeeee; border:1px solid #e7e7e7 !important;
}
input[type="radio"]{
display:none;

View File

@@ -5,31 +5,58 @@ SpoqaHanSansNeo
======================*/
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../font/SpoqaHanSansNeo-Thin.woff') format('woff');
src: url('../font/SpoqaHanSansNeo-Thin.woff2') format('woff2');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../font/SpoqaHanSansNeo-Light.woff') format('woff');
src: url('../font/SpoqaHanSansNeo-Light.woff2') format('woff2');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../font/SpoqaHanSansNeo-Regular.woff') format('woff');
src: url('../font/SpoqaHanSansNeo-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../font/SpoqaHanSansNeo-Medium.woff') format('woff');
src: url('../font/SpoqaHanSansNeo-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'SpoqaHanSansNeo';
src: url('../font/SpoqaHanSansNeo-Bold.woff') format('woff');
src: url('../font/SpoqaHanSansNeo-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
}
/*======================
LGSmHa
======================*/
@font-face {
font-family: 'LGSmHa';
src: url('../font/LGSmHaL.woff2') format('woff2');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'LGSmHa';
src: url('../font/LGSmHaR.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'LGSmHa';
src: url('../font/LGSmHaSB.woff2') format('woff2');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'LGSmHa';
src: url('../font/LGSmHaB.woff2') format('woff2');
font-weight: 700;
font-style: normal;
}
@@ -45,6 +72,16 @@ body{
.div-cont {width: 1200px; padding: 0 30px; box-sizing: border-box; margin: auto;}
/*
#스크롤바
*/
::-webkit-scrollbar {width:5px; height: 5px; border: 0px solid #fff; background: rgba(140, 140, 140, 0.0);}
::-webkit-scrollbar-button:start:decrement, ::-webkit-scrollbar-button:end:increment {display: block; height: 4px; background:rgba(0,0,0,0)}
::-webkit-scrollbar-track {background: rgba(140,140,140,0.0); -webkit-border-radius: 10px; border-radius:10px; -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,.0)}
::-webkit-scrollbar-thumb {height: 50px; width: 50px; background: rgba(20,20, 20, .1); -webkit-border-radius: 8px; border-radius: 8px; -webkit-box-shadow: inset 0 0 4px rgba(0,0,0,.0)}
/*======================
#logo
@@ -81,9 +118,13 @@ body{
.dimmed.open {display: block !important;}
.popup-wrap {display: none;}
.popup-wrap.open {display: block !important;}
.popup {width: 390px; border-radius: 8px; background: #fff; padding: 0 30px; box-sizing: border-box; border: 1px solid rgba(197,197,197,0.36); box-shadow: 2px 2px 8px rgba(171,171,171,0.30); position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%); -webkit-transform: translate(-50%,-50%); -moz-transform: translate(-50%,-50%); -o-transform: translate(-50%,-50%); display: none;}
.popup {width: 390px; border-radius: 12px; background: #fff; padding: 0 30px; box-sizing: border-box; border: 1px solid rgba(197,197,197,0.36); box-shadow: 2px 2px 8px rgba(171,171,171,0.30); position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%); -webkit-transform: translate(-50%,-50%); -moz-transform: translate(-50%,-50%); -o-transform: translate(-50%,-50%); display: none;
max-height: 90vh; overflow: auto;}/*스크린 height 100%를 벗어나는 긴 팝업의 경우 추가 class*/
.popup.open {display: block !important;}
.popup .pop-head {padding: 30px 0 25px;}
.popup .pop-head {padding: 30px 0 25px;
position: sticky; z-index: 999; top:0; left:30px; background: #fff; /*팝업 스크롤 시 타이틀 고정 */
}
.popup .pop-head .pop-tit {font-size: 18px; color: #222222; letter-spacing: -1px; line-height: 100%;}
.popup .btn-close {width: 30px; height: 30px; position: absolute; top: 0; right: 0; background: url("../images/icon-close.png") no-repeat center center; background-size: 11px; border: none;}
.popup .pop-cont {}
@@ -91,8 +132,8 @@ body{
.popup .pop-cont p + p {margin-top: 10px;}
.popup .pop-btn1 {display: flex; justify-content: flex-end; align-items: center; margin: 35px 0 25px;}
.popup .pop-btn2 {display: flex; justify-content: space-between; align-items: center; margin: 35px 0 25px;}
.popup .pop-btn1 button {width: 49%; height: 42px; font-size: 16px; font-weight: 400; letter-spacing: -1.1px;}
.popup .pop-btn2 button {width: 49%; height: 42px; font-size: 16px; font-weight: 400; letter-spacing: -1.1px;}
.popup .pop-btn1 button {width: 49%; height: 40px; font-size: 16px; font-weight: 400; letter-spacing: -1.1px;}
.popup .pop-btn2 button {width: 49%; height: 40px; font-size: 16px; font-weight: 400; letter-spacing: -1.1px;}

View File

@@ -307,7 +307,7 @@ header .user_wrap .user_info .logout {
.main_menu > li.stats.is-current .menu_btn { background-image: url(../images/icon-stats-on.png); }
.main_menu > li.system.is-current .menu_btn { background-image: url(../images/icon-system-on.png); }
.main_menu > li .sub_menu_wrap { padding:0 10px 10px; display:none; }
.main_menu > li .sub_menu_wrap { padding:0 10px 10px; display:none; margin-top: 5px; }
.main_menu > li.is-current .sub_menu_wrap { display: block; }
@@ -317,7 +317,6 @@ header .user_wrap .user_info .logout {
.contents {
padding: 0 4.16vw;
width: 100%;
@@ -332,7 +331,7 @@ header .user_wrap .user_info .logout {
background-color: #fff;
width: 100%;
border-radius: 24px;
padding: 15px 0;
padding: 0 0 15px 0;
margin-bottom: 70px;
}
@@ -351,8 +350,8 @@ header .user_wrap .user_info .logout {
-ms-flex-align: center;
align-items: center;
border-bottom: 1px solid #d5d3e6;
padding: 0 40px;
margin-bottom: 27px;
padding: 21px 0px 0 0px;
margin: 0 40px 27px 40px;
}
.contents .top_wrap .title {
@@ -370,6 +369,33 @@ header .user_wrap .user_info .logout {
letter-spacing: -0.025em;
}
.contents .top_tab {
position: relative; margin: 0 40px; height: 45px; border-bottom: 1px solid #ddddeb; margin-bottom: 40px; display: flex;
font-size: 16px; text-align: center ;
}
.contents .top_tab a.on {
background: url("../images/tab_arrow.png") #fff no-repeat; background-position: 20px center; border: 1px solid #ddddeb; border-bottom: 1px solid #ffffff;
color: #d82e89; font-weight: 500;
}
.contents .top_tab a.on:hover {
background: url("../images/tab_arrow.png") #fff no-repeat; background-position: 20px center; border: 1px solid #ddddeb; border-bottom: 1px solid #ffffff;
color: #d82e89; font-weight: 500;
}
.contents .top_tab a {
background: #ececf3; border: 1px solid #ececf3; border-bottom: 1px solid #ddddeb; height: 45px;padding: 10px 20px; min-width: 180px; display: inline-block; border-radius: 9px 9px 0 0 ; cursor: pointer;
color: #a5a5bd;font-weight: 500;
}
.contents .top_tab a:hover {
background: #bdbde0; border: 1px solid #bdbde0; border-bottom: 1px solid #ddddeb;
color: #ffffff;font-weight: 500;
}
.contents .search_wrap {
background-color: #f6f6f8;
display: -webkit-box;
@@ -381,6 +407,17 @@ header .user_wrap .user_info .logout {
align-items: flex-end;
border-radius: 4px;
margin-bottom: 50px;
flex-wrap: wrap;
}
.contents .search_wrap .group{
width: 100%;
display: flex;
align-items: flex-end;
}
.contents .search_wrap .group + .group{
margin-top: 20px;
}
.contents .search_wrap button.grey {
@@ -410,7 +447,7 @@ header .user_wrap .user_info .logout {
color: #a3a3a3;
}
.contents .select_box select {
.contents select {
width: 100%;
height: 40px;
border: 1px solid #c9c9c9;
@@ -430,6 +467,14 @@ header .user_wrap .user_info .logout {
color: #000;
}
.contents .NumberSe {
float:right;
min-width:90px;
width:auto;
margin-left:10px;
margin-top:-7px;
}
.contents .input_box {
display: -webkit-box;
display: -ms-flexbox;
@@ -449,14 +494,19 @@ header .user_wrap .user_info .logout {
color: #a3a3a3;
}
.contents .input_box .label:focus {
color: #000;
}
.contents .input_box input {
width: 100%;
height: 40px;
border: 1px solid #c9c9c9;
position: relative;
background: url(../images/icon-search.png) no-repeat 6% center/14px auto;
background-color: #fff;
padding-left: 43px;
border-radius: 4px;
}
@@ -476,12 +526,12 @@ header .user_wrap .user_info .logout {
color: #c9c9c9;
}
.contents .input_box.id {
.contents .id {
position: relative;
margin-left: 10px;
}
.contents .input_box.id:before {
.contents .id:before {
content: '';
position: absolute;
top: 25px;
@@ -491,6 +541,95 @@ header .user_wrap .user_info .logout {
background-color: #e8e8f1;
}
/* input cal + search-box*/
.w35{width:35%;}
.contents .table.table_form.m50{margin-bottom: 50px;}
.contents .input_box.cal{
display: inline-block;
width: 27.34%;
}
.contents .input_box.cal label {
display: block;
}
.contents .input_box.cal input {
display: inline-block;
width: 48%;
float: left;
background: #fff url(../images/icon-calender.png) no-repeat right 6% center;
}
.contents .input_box.cal input + input{
margin-left: 4%;
}
.contents .input_box.cal .description{
position: absolute; margin: 10px 0 0 10px; color:#666; font-size: 13px; font-weight: 400;
}
.contents .input_box .search-box {
background: #fff url(../images/icon-search.png) no-repeat 6% center/14px auto;
padding-left: 43px;
}
.input-address input:nth-child(1){
width: 98px;
}
.input-address input:nth-child(2){
width: calc(100% - 480px);
}
.input-address input:nth-child(3){
width: 344px;
}
.input-bnumber input:nth-child(1){
width: 62px;
}
.input-bnumber input:nth-child(2){
width: 52px;
}
.input-bnumber input:nth-child(3){
width: 116px;
}
.input-double{
display: flex;
}
.input-memo{
margin: 5px 0;
display: flex;
}
.input-double input, .button-double button{
width: calc(37.5% - 5px) !important;
}
.btn-a{
width: auto !important;
display: inline-flex !important;
}
.input-memo input{
height: 240px !important;
width: 86%;
}
.contents .two-input{
display: inline-flex;
align-items: flex-end;
}
.contents .two-input .input_box{
width: 100%;
}
.contents .button {
height: 40px;
color: #fff;
@@ -512,6 +651,7 @@ header .user_wrap .user_info .logout {
.contents .button.grey {
background-color: #35354f;
font-size: 16px;
padding: 0 15px;
}
.contents .button.grey:hover {
@@ -539,8 +679,36 @@ header .user_wrap .user_info .logout {
border-color: #000;
}
/*icon button*/
.download::before {
content:'';
background: url(../images/icon-download.png) no-repeat 0 0;
width:23px;
height:23px;
margin-right: 5px;
}
.add::before {
content:'';
background: url(../images/icon-add.png) no-repeat center center;
width:24px;
height:24px;
margin-right: 5px;
margin-top: 2px;
}
.del::before {
content:'';
background: url(../images/icon-del.png) no-repeat center center;
width:24px;
height:24px;
margin-right: 5px;
margin-top: 2px;
}
.contents .info {
padding: 0 30px;
padding: 0 40px;
margin-bottom: 10px;
display: -webkit-box;
display: -ms-flexbox;
@@ -550,17 +718,23 @@ header .user_wrap .user_info .logout {
justify-content: space-between;
}
.contents .info .count {
.info .count {
font-size: 16px;
position: relative;
padding-left: 10px;
}
.contents .info .count span {
.info .count span {
color: #eb008b;
}
.contents .info .count:before {
.info .count p{
color: #666666;
font-size: 14px;
display: inline-flex;
}
.info .count:before {
content: '';
position: absolute;
top: 10px;
@@ -574,6 +748,7 @@ header .user_wrap .user_info .logout {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-top: -7px;
}
.contents .info .title {
@@ -593,9 +768,129 @@ header .user_wrap .user_info .logout {
background-color: #eb008b;
}
/*pagination*/
.contents .pagination .arrow-btn button{
border:none;
padding: 0 5px;
}
.btn-first, .btn-prev{
background:url(../images/icon-pgn-l.png) no-repeat;
width:24px;
height:24px;
}
.btn-next, .btn-last{
background:url('../images/icon-pgn-r.png') no-repeat;
width:24px;
height:24px;
}
.btn-first,.btn-last{background-position: 0px 0px;}
.btn-first:hover, .btn-last:hover{background-position: 0px -48px;}
.btn-prev, .btn-next{background-position: 0px -24px;}
.btn-prev:hover, .btn-next:hover{background-position: 0px -72px;}
.contents .pagination {
display:flex;
justify-content: center;
margin-bottom: 50px;
}
.contents .pagination ul{
display:flex;
align-items:center;
}
.contents .pagination ul li a{
color:#9a9a9a;
font-size: 14px;
padding: 0 15px;
}
.contents .pagination ul li a:hover{
color:#000;
text-decoration: underline;
}
/*contents table 추가*/
.contents .table table .arrow_box {
display: none;
background-color: #fff;
border: #666666 solid 1px;
border-radius: 4px;
color: #666666;
font-size: 14px;
font-weight: 500;
letter-spacing: -0.25px;
margin-top: 16.8px;
padding: 10px 20px;
position: absolute;
min-width: 120px;
z-index: 100;
left: 42px;
}
.contents .table table .arrow_box:before{
border-color: #666666 transparent;
border-style: solid;
border-width: 0 6px 8px 6.5px;
content: '';
display: block;
left: 20px;
position: absolute;
bottom: 100%;
width: 0;
z-index: 0;
}
.contents .table table .arrow_box:after {
border-color: #fff transparent;
border-style: solid;
border-width: 0 6px 8px 6.5px;
content: '';
display: block;
left: 20px;
position: absolute;
bottom: 99%;
width: 0;
z-index: 1;
}
.contents .table.calculate table td, .contents .table.calculate table th{
border-left: 1px solid #dadae6;
}
.contents .table.calculate table td:nth-child(1), .contents .table.calculate table tr:nth-child(1) th:nth-child(1){
border-left: 0;
}
.contents .table table .total{
background-color: #ececf3;
}
.contents .table table td span {cursor: pointer;}
.contents .table table td .linkstyle {cursor: pointer; text-decoration: underline;}
.contents .table table td .linkstyle:hover {color:#eb008b;}
.contents .table table td span:hover + p.arrow_box {
display: block;
}
.contents .table.table_form .tr_input td{
padding: 0;
}
.contents .table.table_form .tr_input .td_radio{
padding-left: 10px;
}
.contents .table {
color: #333333;
padding: 0 30px;
padding: 0 40px;
margin-bottom: 65px;
}
@@ -604,6 +899,7 @@ header .user_wrap .user_info .logout {
text-align: center;
border-top: 2px solid #69677e;
border-bottom: 1px solid #a4a4b0;
table-layout: fixed;
}
.contents .table table thead {
@@ -617,7 +913,7 @@ header .user_wrap .user_info .logout {
.contents .table table th {
font-weight: 500;
height: 50px;
position: relative;
position: relative; font-size: 14px;
}
.contents .table table tr {
@@ -626,12 +922,12 @@ header .user_wrap .user_info .logout {
border-bottom: 1px solid #dadae6;
}
.contents .table table tr:hover {
.contents .table table tbody tr:not(.table_form table tr):hover {
background-color: #fafaff;
}
.contents .table table td {
position: relative;
position: relative; font-size: 14px;
}
.contents .table table td a {
@@ -681,15 +977,16 @@ header .user_wrap .user_info .logout {
}
.contents .table.table_form {
font-size: 16px;
font-size: 14px;
margin-bottom: 24px;
}
.contents .table.table_form th {
background-color: #f7f7f7;
width: 9%;
width: 11%;
text-align: left;
padding-left: 20px;
font-size: 14px;
}
.contents .table.table_form th.center {
@@ -699,6 +996,7 @@ header .user_wrap .user_info .logout {
.contents .table.table_form td {
text-align: left;
padding-left: 10px;font-size: 14px;
}
.contents .table.table_form td.check {
@@ -741,14 +1039,15 @@ header .user_wrap .user_info .logout {
background-color: #f7f7f7;
}
.contents .table.table_form .tr_input input[type="text"] {
.contents .table.table_form .tr_input input[type="text"], .contents .table.table_form .tr_input select {
border: 1px solid #c9c9c9;
border-radius: 4px;
height: 40px;
margin-left: 10px;
font-size: 14px;
}
.contents .table.table_form .tr_input.w30 input[type="text"] {
.contents .table.table_form .tr_input.w30 input[type="text"], .contents .table.table_form .tr_input.w30 select {
width: 30%;
}
@@ -760,8 +1059,8 @@ header .user_wrap .user_info .logout {
width: 98%;
}
.contents .table.table_form .tr_input input[type="radio"] + label:nth-child(2) {
margin: 0 30px 0 10px;
.contents .table.table_form input[type="radio"] + label:nth-child(2) {
margin: 0 30px 0 0;
}
.contents .pop-btn2 {
@@ -805,10 +1104,18 @@ header .user_wrap .user_info .logout {
background-color: #c7c7c7;
}
.popup{
font-family: 'SpoqaHanSansNeo';
}
.popup.popup_form {
width: 525px;
}
.popup.popup_form .info .count {
margin-bottom: 12px;
}
.popup.popup_form .pop-head {
border-bottom: 1px solid #d5d3e6;
padding-bottom: 0;
@@ -864,7 +1171,7 @@ header .user_wrap .user_info .logout {
padding: 0 0 0 10px;
}
.popup.popup_form table td input {
.popup input {
width: 100%;
height: 40px;
border: 1px solid #c9c9c9;
@@ -872,19 +1179,19 @@ header .user_wrap .user_info .logout {
font-size: 16px;
}
.popup.popup_form table td input::-webkit-input-placeholder {
.popup input::-webkit-input-placeholder {
color: #c9c9c9;
}
.popup.popup_form table td input:-ms-input-placeholder {
.popup input:-ms-input-placeholder {
color: #c9c9c9;
}
.popup.popup_form table td input::-ms-input-placeholder {
.popup input::-ms-input-placeholder {
color: #c9c9c9;
}
.popup.popup_form table td input::placeholder {
.popup input::placeholder {
color: #c9c9c9;
}
@@ -907,7 +1214,7 @@ header .user_wrap .user_info .logout {
color: #333333;
}
.popup.popup_form table .input_search {
.popup .input_search {
height: 50px;
display: -webkit-box;
display: -ms-flexbox;
@@ -920,7 +1227,7 @@ header .user_wrap .user_info .logout {
align-items: center;
}
.popup.popup_form table .input_search input[type="text"] {
.popup .input_search input[type="text"] {
position: relative;
background: url(../images/icon-search.png) no-repeat 6% center/14px auto;
background-color: #fff;
@@ -929,23 +1236,23 @@ header .user_wrap .user_info .logout {
width: 72%;
}
.popup.popup_form table .input_search input[type="text"]::-webkit-input-placeholder {
.popup .input_search input[type="text"]::-webkit-input-placeholder {
color: #c9c9c9;
}
.popup.popup_form table .input_search input[type="text"]:-ms-input-placeholder {
.popup .input_search input[type="text"]:-ms-input-placeholder {
color: #c9c9c9;
}
.popup.popup_form table .input_search input[type="text"]::-ms-input-placeholder {
.popup .input_search input[type="text"]::-ms-input-placeholder {
color: #c9c9c9;
}
.popup.popup_form table .input_search input[type="text"]::placeholder {
.popup .input_search input[type="text"]::placeholder {
color: #c9c9c9;
}
.popup.popup_form table .button {
.popup .button {
height: 40px;
color: #fff;
border-radius: 4px;
@@ -963,15 +1270,161 @@ header .user_wrap .user_info .logout {
margin-left: 10px;
}
.popup.popup_form table .button.grey {
.popup .button.grey {
background-color: #35354f;
font-size: 16px;
}
.popup.popup_form table .button.grey:hover {
.popup .button.grey:hover {
background-color: #0a0b24;
}
/*customer popup*/
.popup.b-popup{
width:700px;
}
.popup.price table th{
width:20%;
}
.popup label{
font-size: 13px;
letter-spacing: -0.025em;
margin-bottom: 6px;
color: #333333;
}
.popup .number{
color:#000000;
font-weight: bold;
}
.popup .number.blue{color:#0073d4;}
.popup .number.red{color:#ff3600;}
.popup.popup_form .table-c{
table-layout: fixed;
margin-top: 10px;
}
.popup.popup_form .table-c th, .popup.popup_form .table-c td{
padding: 0;
text-align:center;
}
.popup.b-popup tr th:nth-child(1){
width:60%;
}
.popup.b-popup tr th:nth-child(2){
width:10%;
}
.popup.b-popup tr th:nth-child(3), .popup.b-popup tr th:nth-child(4){
width:15%;
}
.popup.b-popup tr .memo{
text-align: left;
padding: 0 0 0 10px;
}
.popup.b-popup tr:nth-child(1) .memo:nth-child(1){
height: 100px;
display: block;
overflow: auto;
}
.popup .pop-cont.bottom{
margin-top: 20px;
}
.popup.popup_form .pop-btn2 .download {
display: flex;
justify-content: center;
align-items: center;
}
.popup.popup_form .pop-btn2.bulk{
justify-content: space-between;
margin-bottom: 20px;
}
.popup.popup_form .pop-btn2.bulk button{
width: 49%;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
justify-content: normal;
}
.popup.popup_form .pop-btn2.bulk button:nth-child(1)::before{
content: '';
background: url(../images/icon-f-download.png) no-repeat 0 0;
width: 23px;
height: 23px;
margin: 2px 5px 0 15px;
}
.popup.popup_form .pop-btn2.bulk button:nth-child(2)::before{
content: '';
background: url(../images/icon-f-upload.png) no-repeat 0 0;
width: 23px;
height: 23px;
margin: 2px 5px 0 15px;
}
.popup.popup_form .btn-default{
color: #333333;
border-radius: 6px;
border: 1px solid #a1a1a1;
font-size: 14px;
}
.popup.popup_form .file{
color: #656565;
margin-bottom: 18px;
}
.popup.popup_form .file button{
background: #e4e4e4 url(../images/icon-delete.png) no-repeat center center;
width: 24px;
height: 24px;
display: inline-block;
border-radius: 50%;
position: relative;
top: 6px;
left: 5px;
border: none;
}
.popup.popup_form.b-popup .input_add{
padding: 5px 0px 5px 0px;
}
.popup.popup_form.b-popup .input_add div{
display: flex;
justify-content: space-between;
}
.popup.popup_form.b-popup .input_add div input:nth-child(1){
margin-right: 5px;
width: 95px;
}
.input_add .button.add{
min-width: 40px;
margin-left: 2%;
}
.popup.popup_form.b-popup .input_add div:nth-child(2){
width: 89%;
padding-top: 5px;
}
/*# sourceMappingURL=style.css.map */

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,6 +1,8 @@
/*(function(){
(function(){
const menuList = document.querySelectorAll('.main_menu .is-sub');
for(const menu of menuList){
menu.addEventListener('click', (e)=> {
if(e.target.classList.contains('menu_target') || e.target.classList.contains('menu_btn')){
@@ -16,29 +18,18 @@
}
})
}
})();*/
})();
/*const ModalOpen = target =>{
console.log("ModalOpen");
function ModalOpen(target) {
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = document.getElementsByClassName(target);
dimmed[0].style.display = 'block';
wrap[0].style.display = 'block';
obj[0].style.display = 'block';
}*/
// eslint-disable-next-line no-unused-vars
/*function ModalOpen(target) {
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = document.getElementsByClassName(target);
dimmed[0].style.display = 'block';
wrap[0].style.display = 'block';
obj[0].style.display = 'block';
}*/
// eslint-disable-next-line no-unused-vars
/*function ModalClose() {
}
function ModalClose() {
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = wrap[0].childElementCount
@@ -49,7 +40,6 @@
target[i].style.display = 'none';
}
}
// eslint-disable-next-line no-unused-vars
function userInfoToggle(){
var click = "clicked";
var userBtn = document.querySelector('.user_wrap .user');
@@ -59,8 +49,4 @@ function userInfoToggle(){
else{
userBtn.classList.add(click);
}
}*/
export default{
ModalOpen
}

View File

@@ -1,9 +1,9 @@
import httpClient from '@/common/http-client';
// 주소찾기
const getAddressList = params => {
return httpClient.get('/api/comm/address', { params: params })
}
export default {
getAddressList
}
import httpClient from '@/common/http-client';
// 주소찾기
const getAddressList = params => {
return httpClient.get('/api/comm/address', { params: params })
}
export default {
getAddressList
}

View File

@@ -1,10 +1,13 @@
const { VUE_APP_TEST_PROP, NODE_ENV = '' } = process.env;
const environment = NODE_ENV.toLowerCase();
const testProp = VUE_APP_TEST_PROP;
const consts = {
tokenPart1: 'JwtPart1'
}
export { environment, testProp, consts };
const { VUE_APP_TEST_PROP, NODE_ENV = '' } = process.env;
const environment = NODE_ENV.toLowerCase();
const testProp = VUE_APP_TEST_PROP;
const consts = {
tokenPart1: 'JwtPart1',
tokenPart2: 'JwtPart2',
tokenPart3: 'JwtPart3',
tokenPart4: 'JwtPart4'
}
export { environment, testProp, consts };

View File

@@ -1,143 +1,143 @@
import xlsx from 'xlsx';
const xlsxUtils = {
filename: '',
data: [],
header: [],
options: {},
summary: {
isUse: false,
position: '',
data: null,
title: { replaceKeys: [], name: '' }
},
visibleDataOrder: [],
instance: undefined,
createInstance() {
return new Promise((resolve, reject) => {
this.instance = document.createElement('table');
resolve();
});
},
createHeader() {
return new Promise((resolve, reject) => {
let header = this.header;
/*
if (!Array.isArray(this.header[0])) {
header.push(this.header);
} else {
header = this.header;
}
*/
let thead = document.createElement('thead');
for (let row of header) {
let tr = document.createElement('tr');
for (let h of row) {
let rowspan = h.rowspan || '1';
let colspan = h.colspan || '1';
let th = document.createElement('th');
th.setAttribute('rowspan', rowspan);
th.setAttribute('colspan', colspan);
//th.setAttribute('align', 'center');
th.innerText = h.name;
tr.appendChild(th);
}
thead.appendChild(tr);
}
this.instance.appendChild(thead);
resolve();
});
},
createDataRows() {
return new Promise((resolve, reject) => {
let tbody = document.createElement('tbody');
if (this.options.summary != undefined && this.options.summary.isUse) {
this.summary = this.options.summary;
}
if (this.summary.isUse && this.summary.position === 'first') {
this.appendDataRow(tbody, this.summary.data, true);
}
this.appendDataRow(tbody, this.data, false);
if (this.summary.isUse && this.summary.position === 'last') {
this.appendDataRow(tbody, this.summary.data, true);
}
this.instance.appendChild(tbody);
resolve();
});
},
appendDataRow(tbody, data, isSummary) {
for (let row of data) {
let tr = document.createElement('tr');
if (isSummary) {
let td = document.createElement('td');
td.innerText = this.summary.title.name;
td.setAttribute('colspan', this.summary.title.replaceKeys.length);
//td.setAttribute('align', 'center');
tr.appendChild(td);
}
for (let cellkey of this.visibleDataOrder) {
if (isSummary && this.summary.title.replaceKeys.indexOf(cellkey) > -1) continue;
let td = document.createElement('td');
td.innerText = row[cellkey];
tr.appendChild(td);
}
tbody.appendChild(tr);
}
return tbody;
},
getVisibleDataOrder() {
let dataOrder = [];
if (Array.isArray(this.options.dataOrder)) {
dataOrder = this.options.dataOrder;
} else if (this.options.dataOrder === 'header') {
for (let row of this.header) {
for (let h of row) {
if (h.key != undefined && h.key != null && h.key !== '') {
dataOrder.push(h.key);
}
}
}
} else {
dataOrder = Object.keys(this.data[0]);
}
this.visibleDataOrder = dataOrder;
},
export(data, filename, options) {
this.data = data;
this.filename = filename;
this.header = options.header;
this.options = options;
this.getVisibleDataOrder();
return new Promise((resolve, reject) => {
this.createInstance().then(() => {
this.createHeader().then(() => {
this.createDataRows().then(() => {
this.exportTableToXlsx();
resolve();
});
});
});
});
},
exportTableToXlsx() {
let config = { raw: true, type: 'string' };
let ws = xlsx.utils.table_to_sheet(this.instance, config);
let wb = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(wb, ws, 'Sheet1');
xlsx.writeFile(wb, this.filename);
}
};
export default xlsxUtils;
import xlsx from 'xlsx';
const xlsxUtils = {
filename: '',
data: [],
header: [],
options: {},
summary: {
isUse: false,
position: '',
data: null,
title: { replaceKeys: [], name: '' }
},
visibleDataOrder: [],
instance: undefined,
createInstance() {
return new Promise((resolve, reject) => {
this.instance = document.createElement('table');
resolve();
});
},
createHeader() {
return new Promise((resolve, reject) => {
let header = this.header;
/*
if (!Array.isArray(this.header[0])) {
header.push(this.header);
} else {
header = this.header;
}
*/
let thead = document.createElement('thead');
for (let row of header) {
let tr = document.createElement('tr');
for (let h of row) {
let rowspan = h.rowspan || '1';
let colspan = h.colspan || '1';
let th = document.createElement('th');
th.setAttribute('rowspan', rowspan);
th.setAttribute('colspan', colspan);
//th.setAttribute('align', 'center');
th.innerText = h.name;
tr.appendChild(th);
}
thead.appendChild(tr);
}
this.instance.appendChild(thead);
resolve();
});
},
createDataRows() {
return new Promise((resolve, reject) => {
let tbody = document.createElement('tbody');
if (this.options.summary != undefined && this.options.summary.isUse) {
this.summary = this.options.summary;
}
if (this.summary.isUse && this.summary.position === 'first') {
this.appendDataRow(tbody, this.summary.data, true);
}
this.appendDataRow(tbody, this.data, false);
if (this.summary.isUse && this.summary.position === 'last') {
this.appendDataRow(tbody, this.summary.data, true);
}
this.instance.appendChild(tbody);
resolve();
});
},
appendDataRow(tbody, data, isSummary) {
for (let row of data) {
let tr = document.createElement('tr');
if (isSummary) {
let td = document.createElement('td');
td.innerText = this.summary.title.name;
td.setAttribute('colspan', this.summary.title.replaceKeys.length);
//td.setAttribute('align', 'center');
tr.appendChild(td);
}
for (let cellkey of this.visibleDataOrder) {
if (isSummary && this.summary.title.replaceKeys.indexOf(cellkey) > -1) continue;
let td = document.createElement('td');
td.innerText = row[cellkey];
tr.appendChild(td);
}
tbody.appendChild(tr);
}
return tbody;
},
getVisibleDataOrder() {
let dataOrder = [];
if (Array.isArray(this.options.dataOrder)) {
dataOrder = this.options.dataOrder;
} else if (this.options.dataOrder === 'header') {
for (let row of this.header) {
for (let h of row) {
if (h.key != undefined && h.key != null && h.key !== '') {
dataOrder.push(h.key);
}
}
}
} else {
dataOrder = Object.keys(this.data[0]);
}
this.visibleDataOrder = dataOrder;
},
export(data, filename, options) {
this.data = data;
this.filename = filename;
this.header = options.header;
this.options = options;
this.getVisibleDataOrder();
return new Promise((resolve, reject) => {
this.createInstance().then(() => {
this.createHeader().then(() => {
this.createDataRows().then(() => {
this.exportTableToXlsx();
resolve();
});
});
});
});
},
exportTableToXlsx() {
let config = { raw: true, type: 'string' };
let ws = xlsx.utils.table_to_sheet(this.instance, config);
let wb = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(wb, ws, 'Sheet1');
xlsx.writeFile(wb, this.filename);
}
};
export default xlsxUtils;

View File

@@ -1,105 +1,122 @@
import axios from 'axios';
import { testProp } from './config';
const config = {
//baseURL: 'http://localhost:7070',
// baseURL: apiBaseUrl,
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
timeout: 120000 // timeout은 120초로 설정
};
const httpClient = axios.create(config);
const authInterceptor = config => {
// frontend와 backend의 origin이 다른 경우
// devServer.proxy 설정을 하던지 baseURL과 withCredentials 설정을 해야 한다.
// cookie, header 등에 자격정보 설정이 필요한 api는 true 설정으로 호출해야 하고
// 자격정보 설정이 필요없는 api는 withCredentials=false 설정으로 호출해야 한다.
// config.withCredentials = !config.url.startsWith('/api/public/');
console.log("Test Url : "+ config.url);
/*if(config.url == '/api/auth/login'){
config.baseURL = "http://localhost:3000";
}*/
return config;
};
const loggerInterceptor = config => {
console.log('testProp:', testProp);
console.log('request url:', config.url, 'params:', config.data);
return config;
};
let loadOverlap = [];
const loadingLayer = (type, config) => {
/*
get: httpClient.get(url, { params: { ... }, headers: {"show-layer": "Yes"} }) // in 2nd property
post: httpClient.post(url, params, { headers: {"show-layer": "Yes"} }) // 3rd property
*/
if (config.headers['Show-Layer'] == 'Yes') {
if (type) {
loadOverlap.push('add');
} else {
loadOverlap.pop();
}
if (loadOverlap.length > 0) {
document.querySelector('html > body').style.overflow = 'hidden'; // 스크롤 block
document.getElementsByClassName('loading_layer')[0].style.display = 'block';
} else {
document.querySelector('html > body').style.removeProperty('overflow'); // 스크롤 allow
document.getElementsByClassName('loading_layer')[0].style.display = 'none';
}
}
};
/*const loadingLayerInterceptor = config => {
loadingLayer(true, config);
return config;
};*/
/** Adding the request interceptors */
httpClient.interceptors.request.use(authInterceptor);
httpClient.interceptors.request.use(loggerInterceptor);
//httpClient.interceptors.request.use(loadingLayerInterceptor);
/** Adding the response interceptors */
httpClient.interceptors.response.use(
response => {
//loadingLayer(false, response.config);
console.log('response status:', response.status, 'data:', response.data);
return response;
},
error => {
console.log(error);
if (error.response != undefined && error.response != null) loadingLayer(false, error.response.config);
else loadingLayer(false, error.config);
if (error.code === 'ECONNABORTED') {
alert('서비스가 지연되고 있습니다. 잠시 후 확인하시고 다시 시도해주세요.');
return Promise.reject(error);
} else if (error.response.status == 401 || error.response.status == 418) {
alert('세션이 만료되었습니다.');
window.top.location.href = '/login';
} else if (error.response.status == 500) {
if (error.response.data != null && error.response.data.message == '511 NETWORK_AUTHENTICATION_REQUIRED') {
alert('웹템플릿 IP가 브랜드포털에 등록이 필요합니다. 기술지원에 문의해주세요.');
return Promise.reject(error);
} else {
window.top.location.href = '/view/error/500';
}
} else if (error.response.status == 511) {
alert('웹템플릿 IP가 브랜드포털에 등록이 필요합니다. 기술지원에 문의해주세요.');
return Promise.reject(error);
} else if (error.message == 'Network Error') {
alert('네트워크 오류가 발생했습니다. 잠시 후 다시 시도해주세요.');
return Promise.reject(error);
} else {
console.log('response error:', error);
return Promise.reject(error);
}
}
);
export default httpClient;
import axios from 'axios';
import { testProp } from './config';
import tokenSvc from '@/common/token-service';
import { consts } from './config';
const config = {
//baseURL: 'http://localhost:7070',
// baseURL: apiBaseUrl,
headers: {
'X-Requested-With': 'XMLHttpRequest'
},
timeout: 120000 // timeout은 120초로 설정
};
const httpClient = axios.create(config);
const authInterceptor = config => {
// frontend와 backend의 origin이 다른 경우
// devServer.proxy 설정을 하던지 baseURL과 withCredentials 설정을 해야 한다.
// cookie, header 등에 자격정보 설정이 필요한 api는 true 설정으로 호출해야 하고
// 자격정보 설정이 필요없는 api는 withCredentials=false 설정으로 호출해야 한다.
// config.withCredentials = !config.url.startsWith('/api/public/');
console.log("Test Url : "+ config.url);
/*if(config.url == '/api/auth/login'){
config.baseURL = "http://localhost:3000";
}*/
return config;
};
const tokenInterceptor = config => {
if(tokenSvc.getAuthorization(consts.tokenPart1) != null){
config.headers.Authorization = tokenSvc.getAuthorization(consts.tokenPart1);
//console.log("getToken : "+config.headers.Authorization);
//config.headers.Authorization = tokenSvc.getToken();
}
return config;
}
const loggerInterceptor = config => {
//console.log('testProp:', testProp);
//console.log('request url:', config.url, 'params:', config.data);
return config;
};
let loadOverlap = [];
const loadingLayer = (type, config) => {
/*
get: httpClient.get(url, { params: { ... }, headers: {"show-layer": "Yes"} }) // in 2nd property
post: httpClient.post(url, params, { headers: {"show-layer": "Yes"} }) // 3rd property
*/
if (config.headers['Show-Layer'] == 'Yes') {
if (type) {
loadOverlap.push('add');
} else {
loadOverlap.pop();
}
if (loadOverlap.length > 0) {
document.querySelector('html > body').style.overflow = 'hidden'; // 스크롤 block
document.getElementsByClassName('loading_layer')[0].style.display = 'block';
} else {
document.querySelector('html > body').style.removeProperty('overflow'); // 스크롤 allow
document.getElementsByClassName('loading_layer')[0].style.display = 'none';
}
}
};
/*const loadingLayerInterceptor = config => {
loadingLayer(true, config);
return config;
};*/
/** Adding the request interceptors */
httpClient.interceptors.request.use(authInterceptor);
httpClient.interceptors.request.use(tokenInterceptor);
httpClient.interceptors.request.use(loggerInterceptor);
//httpClient.interceptors.request.use(loadingLayerInterceptor);
/** Adding the response interceptors */
httpClient.interceptors.response.use(
response => {
//loadingLayer(false, response.config);
console.log('response status:', response.status, 'data:', response.data);
return response;
},
error => {
console.log(error);
if (error.response != undefined && error.response != null) loadingLayer(false, error.response.config);
else loadingLayer(false, error.config);
if (error.code === 'ECONNABORTED') {
alert('서비스가 지연되고 있습니다. 잠시 후 확인하시고 다시 시도해주세요.');
return Promise.reject(error);
} else if(error.response.status == 401){
alert('세션이 만료되었습니다.');
tokenSvc.removeToken();
window.top.location.href = '/login';
} else if (error.response.status == 418) {
}else if (error.response.status == 500) {
if (error.response.data != null && error.response.data.message == '511 NETWORK_AUTHENTICATION_REQUIRED') {
alert('웹템플릿 IP가 브랜드포털에 등록이 필요합니다. 기술지원에 문의해주세요.');
return Promise.reject(error);
} else {
tokenSvc.removeToken();
window.top.location.href = '/login';
}
} else if (error.response.status == 511) {
alert('웹템플릿 IP가 브랜드포털에 등록이 필요합니다. 기술지원에 문의해주세요.');
return Promise.reject(error);
} else if (error.message == 'Network Error') {
alert('네트워크 오류가 발생했습니다. 잠시 후 다시 시도해주세요.');
return Promise.reject(error);
} else {
alert("else");
console.log('response error:', error);
return Promise.reject(error);
}
}
);
export default httpClient;

View File

@@ -1 +1 @@
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((t=t||self).vdp_translation_ko=t.vdp_translation_ko||{},t.vdp_translation_ko.js=n())}(this,function(){"use strict";function t(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}var n=new(function(){function n(t,e,r,o){!function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}(this,n),this.language=t,this.months=e,this.monthsAbbr=r,this.days=o,this.rtl=!1,this.ymd=!1,this.yearSuffix=""}var e,r,o;return e=n,(r=[{key:"language",get:function(){return this._language},set:function(t){if("string"!=typeof t)throw new TypeError("Language must be a string");this._language=t}},{key:"months",get:function(){return this._months},set:function(t){if(12!==t.length)throw new RangeError("There must be 12 months for ".concat(this.language," language"));this._months=t}},{key:"monthsAbbr",get:function(){return this._monthsAbbr},set:function(t){if(12!==t.length)throw new RangeError("There must be 12 abbreviated months for ".concat(this.language," language"));this._monthsAbbr=t}},{key:"days",get:function(){return this._days},set:function(t){if(7!==t.length)throw new RangeError("There must be 7 days for ".concat(this.language," language"));this._days=t}}])&&t(e.prototype,r),o&&t(e,o),n}())("Korean",["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],["일","월","화","수","목","금","토"]);return n.yearSuffix="년",n.ymd=!0,n});
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):((t=t||self).vdp_translation_ko=t.vdp_translation_ko||{},t.vdp_translation_ko.js=n())}(this,function(){"use strict";function t(t,n){for(var e=0;e<n.length;e++){var r=n[e];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}var n=new(function(){function n(t,e,r,o){!function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")}(this,n),this.language=t,this.months=e,this.monthsAbbr=r,this.days=o,this.rtl=!1,this.ymd=!1,this.yearSuffix=""}var e,r,o;return e=n,(r=[{key:"language",get:function(){return this._language},set:function(t){if("string"!=typeof t)throw new TypeError("Language must be a string");this._language=t}},{key:"months",get:function(){return this._months},set:function(t){if(12!==t.length)throw new RangeError("There must be 12 months for ".concat(this.language," language"));this._months=t}},{key:"monthsAbbr",get:function(){return this._monthsAbbr},set:function(t){if(12!==t.length)throw new RangeError("There must be 12 abbreviated months for ".concat(this.language," language"));this._monthsAbbr=t}},{key:"days",get:function(){return this._days},set:function(t){if(7!==t.length)throw new RangeError("There must be 7 days for ".concat(this.language," language"));this._days=t}}])&&t(e.prototype,r),o&&t(e,o),n}())("Korean",["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],["일","월","화","수","목","금","토"]);return n.yearSuffix="년",n.ymd=!0,n});

View File

@@ -1,38 +1,53 @@
import * as utils from './utils';
import { consts } from './config';
// const KEY_TOKEN = 'access_token';
const tokenSvc = {
getToken() {
// return store.getters['login/getToken'];
// var payload = sessionStorage.getItem(KEY_TOKEN);
var jwtPart1 = utils.getCookie(consts.tokenPart1);
if (!jwtPart1)
return null;
var payload = utils.base64decode(jwtPart1.split('.').pop());
return JSON.parse(payload);
},
removeToken() {
var name = consts.tokenPart1;
document.cookie = name + '=; expires=Thu, 01 Jan 1999 00:00:10 GMT;';
}
// saveToken(jwtPart1) {
// if (!jwtPart1)
// return;
// var payload = utils.base64decode(jwtPart1.split('.').pop());
// console.log('save token:', payload);
// // store.commit('login/saveToken', token);
// sessionStorage.setItem(KEY_TOKEN, payload);
// },
// removeToken() {
// // store.commit('login/removeToken');
// sessionStorage.removeItem(KEY_TOKEN);
// }
};
export default tokenSvc;
import * as utils from './utils';
import { consts } from './config';
// const KEY_TOKEN = 'access_token';
const tokenSvc = {
getToken() {
// return store.getters['login/getToken'];
// var payload = sessionStorage.getItem(KEY_TOKEN);
var jwtPart1 = utils.getCookie(consts.tokenPart1);
if (!jwtPart1)
return null;
var payload = utils.base64decode(jwtPart1.split('.').pop());
return JSON.parse(payload);
},
removeToken() {
var tokenNm1 = consts.tokenPart1;
var tokenNm2 = consts.tokenPart2;
var tokenNm3 = consts.tokenPart3;
var tokenNm4 = consts.tokenPart4;
document.cookie = tokenNm1+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
document.cookie = tokenNm2+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
document.cookie = tokenNm3+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
document.cookie = tokenNm4+'=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
},
getAuthorization(tokenKey){
var jwtPart = utils.getCookie(tokenKey);
if(!jwtPart){
return null;
}
return jwtPart;
},
// saveToken(jwtPart1) {
// if (!jwtPart1)
// return;
// var payload = utils.base64decode(jwtPart1.split('.').pop());
// console.log('save token:', payload);
// // store.commit('login/saveToken', token);
// sessionStorage.setItem(KEY_TOKEN, payload);
// },
// removeToken() {
// // store.commit('login/removeToken');
// sessionStorage.removeItem(KEY_TOKEN);
// }
};
export default tokenSvc;

View File

@@ -1,117 +1,117 @@
/**
* @description This method is responsile for creating the object with mirror key and values
* and also add prefix to values if available
* @param {Array<string>} arr Array of strings
* @param {string} prefix prefix
* @returns {Object} object with mirror keys generated from the array of strings
*/
export const reflectKeys = (arr = [], prefix) =>
arr.reduce((obj, key) => {
const value = prefix ? prefix + ' ' + key : key;
obj[key] = value;
return obj;
}, {});
export const form2obj = function(form) {
var queryStr = serializeForm(form);
return qstr2obj(queryStr);
};
/*!
* Serialize all form data into a query string
* (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Node} form The form to serialize
* @return {String} The serialized form data
*/
export const serializeForm = function(form) {
// Setup our serialized data
var serialized = [];
// Loop through each field in the form
for (var i = 0; i < form.elements.length; i++) {
var field = form.elements[i];
// Don't serialize fields without a name, submits, buttons, file and reset inputs, and disabled fields
if (
!field.name ||
field.disabled ||
field.type === 'file' ||
field.type === 'reset' ||
field.type === 'submit' ||
field.type === 'button'
)
continue;
// If a multi-select, get all selections
if (field.type === 'select-multiple') {
for (var n = 0; n < field.options.length; n++) {
if (!field.options[n].selected) continue;
serialized.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(field.options[n].value));
}
}
// Convert field data to a query string
else if ((field.type !== 'checkbox' && field.type !== 'radio') || field.checked) {
serialized.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value));
}
}
return serialized.join('&');
};
export const qstr2obj = function(qstr) {
let obj = {};
if (qstr) {
qstr.split('&').map(item => {
const [k, v] = item.split('=');
v ? (obj[k] = v) : null;
});
}
return obj;
};
export const getCookie = function(name) {
var value = '; ' + document.cookie;
var parts = value.split('; ' + name + '=');
if (parts.length == 2)
return parts
.pop()
.split(';')
.shift();
};
import { Base64 } from 'js-base64';
export const base64encode = function(str) {
return Base64.encode(str);
};
export const base64decode = function(b64) {
return Base64.decode(b64);
};
export const getGwSuccessCode = function() {
return '10000';
};
export const isGwSuccess = function(code) {
return getGwSuccessCode() == code;
};
let loadOverlap = [];
export const loadingLayer = (type) => {
if (type) {
loadOverlap.push('add');
} else {
loadOverlap.pop();
}
if (loadOverlap.length > 0) {
document.querySelector('html > body').style.overflow = 'hidden'; // 스크롤 block
document.getElementsByClassName('loading_layer')[0].style.display = 'block';
} else {
document.querySelector('html > body').style.removeProperty('overflow'); // 스크롤 allow
document.getElementsByClassName('loading_layer')[0].style.display = 'none';
}
};
/**
* @description This method is responsile for creating the object with mirror key and values
* and also add prefix to values if available
* @param {Array<string>} arr Array of strings
* @param {string} prefix prefix
* @returns {Object} object with mirror keys generated from the array of strings
*/
export const reflectKeys = (arr = [], prefix) =>
arr.reduce((obj, key) => {
const value = prefix ? prefix + ' ' + key : key;
obj[key] = value;
return obj;
}, {});
export const form2obj = function(form) {
var queryStr = serializeForm(form);
return qstr2obj(queryStr);
};
/*!
* Serialize all form data into a query string
* (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Node} form The form to serialize
* @return {String} The serialized form data
*/
export const serializeForm = function(form) {
// Setup our serialized data
var serialized = [];
// Loop through each field in the form
for (var i = 0; i < form.elements.length; i++) {
var field = form.elements[i];
// Don't serialize fields without a name, submits, buttons, file and reset inputs, and disabled fields
if (
!field.name ||
field.disabled ||
field.type === 'file' ||
field.type === 'reset' ||
field.type === 'submit' ||
field.type === 'button'
)
continue;
// If a multi-select, get all selections
if (field.type === 'select-multiple') {
for (var n = 0; n < field.options.length; n++) {
if (!field.options[n].selected) continue;
serialized.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(field.options[n].value));
}
}
// Convert field data to a query string
else if ((field.type !== 'checkbox' && field.type !== 'radio') || field.checked) {
serialized.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value));
}
}
return serialized.join('&');
};
export const qstr2obj = function(qstr) {
let obj = {};
if (qstr) {
qstr.split('&').map(item => {
const [k, v] = item.split('=');
v ? (obj[k] = v) : null;
});
}
return obj;
};
export const getCookie = function(name) {
var value = '; ' + document.cookie;
var parts = value.split('; ' + name + '=');
if (parts.length == 2)
return parts
.pop()
.split(';')
.shift();
};
import { Base64 } from 'js-base64';
export const base64encode = function(str) {
return Base64.encode(str);
};
export const base64decode = function(b64) {
return Base64.decode(b64);
};
export const getGwSuccessCode = function() {
return '10000';
};
export const isGwSuccess = function(code) {
return getGwSuccessCode() == code;
};
let loadOverlap = [];
export const loadingLayer = (type) => {
if (type) {
loadOverlap.push('add');
} else {
loadOverlap.pop();
}
if (loadOverlap.length > 0) {
document.querySelector('html > body').style.overflow = 'hidden'; // 스크롤 block
document.getElementsByClassName('loading_layer')[0].style.display = 'block';
} else {
document.querySelector('html > body').style.removeProperty('overflow'); // 스크롤 allow
document.getElementsByClassName('loading_layer')[0].style.display = 'none';
}
};

View File

@@ -1,228 +1,228 @@
const coreUiMixin = {
directives: {
focus: {
inserted: function(el) {
el.focus();
}
}
},
methods: {
clearInput: function(evt) {
var me = evt.target;
var vname = me.previousElementSibling.name;
this.$data[vname] = '';
me.previousElementSibling.focus();
},
showPhoneNumber: function(str) {
str = str.replace(/[\-\s\/]+/g, '');
if (str.length > 12 || str.length < 10) {
return str;
}
var result =
str.substring(0, str.length - 8) +
'-' +
str.substring(str.length - 8, str.length - 4) +
'-' +
str.substring(str.length - 4, str.length);
return result;
},
/*
openLayer: function(event, callback) {
var myId = event.target.getAttribute('data-id');
var myLayer = document.querySelector('[layer-id="' + myId + '"]');
var btnClose = document.querySelector('[layer-id="' + myId + '"] .btn_close');
myLayer.classList.add('active');
btnClose.addEventListener("click", function() {
myLayer.classList.remove('active');
if (callback != undefined && callback != null) {
callback('');
}
});
if (callback != undefined && callback != null) {
callback(myId);
}
},
*/
openLayer: function(layerId) {
if (layerId == undefined || layerId == null || layerId == '') {
alert('layerId를 설정해 주세요.');
} else {
this.$emit('changeLayerId', layerId);
}
},
closeLayer() {
this.$emit('changeLayerId', '');
},
numberComma(num) {
if (typeof num == undefined || num == null) {
return '';
}
num = num + '';
let point = num.length % 3;
let len = num.length;
let str = num.substring(0, point);
while (point < len) {
if (str != '') {
str += ',';
}
str += num.substring(point, point + 3);
point += 3;
}
return str;
}
}
};
var chkPattern = {
data: function() {
return {};
},
methods: {
setLenth: function(e, len) {
this.cut(e, len);
},
onlyNum: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[0-9]*$/g.exec(str)) {
e.target.value = str.replace(/[^0-9]/gi, '');
}
},
only11Num: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[0-9]*$/g.exec(str)) {
str = str.replace(/[^0-9]/gi, '');
}
if (str.length > 11) {
str = str.substring(0, 11);
}
e.target.value = str;
},
onlyEmail: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[a-zA-Z0-9_\.\-@._-]*$/g.exec(str)) {
e.target.value = str.replace(/[^a-zA-Z0-9_\.\-@._-]/gi, '');
}
},
onlyName: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z]/gi, '');
}
},
onlyTitle: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z0-9]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z0-9]/gi, '');
}
},
onlyText: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z0-9_-]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z0-9_-]/gi, '');
}
},
onlyPassword: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[A-Za-z0-9!@#$%^&*]*$/g.exec(str)) {
e.target.value = str.replace(/[^A-Za-z0-9!@#$%^&*]/gi, '');
}
},
onlyId: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[A-Za-z0-9]*$/g.exec(str)) {
e.target.value = str.replace(/[^A-Za-z0-9]/gi, '');
}
},
onlyIp: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[0-9,.*]*$/g.exec(str)) {
e.target.value = str.replace(/[^0-9,.*]/gi, '');
}
},
onlyRoleNm_Space: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z0-9/\s]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z0-9/\s]/gi, '');
}
},
onlyRoleId_UnderBar: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[a-zA-Z0-9_]*$/g.exec(str)) {
e.target.value = str.replace(/[^a-zA-Z0-9_]/gi, '');
}
},
cut: function(e, len) {
if (typeof len != 'undefined') {
var str = e.target.value;
if (this.bytes(str) > len) {
e.target.value = this.cutBytes(str, len);
}
}
},
cutBytes: function(str, len) {
var count = 0;
for (var i = 0; i < str.length; i++) {
if (escape(str.charAt(i)).length >= 4) count += 2;
else if (escape(str.charAt(i)) != '%0D') count++;
if (count > len) {
if (escape(str.charAt(i)) == '%0A') i--;
break;
}
}
return str.substring(0, i);
},
bytes: function(str) {
var length = 0;
for (var i = 0; i < str.length; i++) {
if (escape(str.charAt(i)).length >= 4) length += 2;
else if (escape(str.charAt(i)) == '%A7') length += 2;
else {
if (escape(str.charAt(i)) != '%0D') length++;
}
}
return length;
},
checkPhone: function(str) {
str = str.replace(/[\-\s\/]+/g, '');
if (str.charAt(0) != '0') {
str = '0' + str;
}
if (str.length < 10 || str.length > 12) {
return '';
}
if (isNaN(str)) {
return '';
}
//if (str.substr(0,2)!="01" && str.substr(0,3)!="070" && str.substr(0,4)!="0505" && str.substr(0,4)!="0503"){return ""; }
//sif (str.substr(0,3)!="010"){return ""; }
return str;
},
checkExcelFile: function(fileObj) {
let reg = /(.*?)\.(xls|xlsx)$/;
if (fileObj == undefined || fileObj == null)
return false;
if (!fileObj.name.match(reg))
return false;
return true;
}
}
};
export { coreUiMixin, chkPattern };
const coreUiMixin = {
directives: {
focus: {
inserted: function(el) {
el.focus();
}
}
},
methods: {
clearInput: function(evt) {
var me = evt.target;
var vname = me.previousElementSibling.name;
this.$data[vname] = '';
me.previousElementSibling.focus();
},
showPhoneNumber: function(str) {
str = str.replace(/[\-\s\/]+/g, '');
if (str.length > 12 || str.length < 10) {
return str;
}
var result =
str.substring(0, str.length - 8) +
'-' +
str.substring(str.length - 8, str.length - 4) +
'-' +
str.substring(str.length - 4, str.length);
return result;
},
/*
openLayer: function(event, callback) {
var myId = event.target.getAttribute('data-id');
var myLayer = document.querySelector('[layer-id="' + myId + '"]');
var btnClose = document.querySelector('[layer-id="' + myId + '"] .btn_close');
myLayer.classList.add('active');
btnClose.addEventListener("click", function() {
myLayer.classList.remove('active');
if (callback != undefined && callback != null) {
callback('');
}
});
if (callback != undefined && callback != null) {
callback(myId);
}
},
*/
openLayer: function(layerId) {
if (layerId == undefined || layerId == null || layerId == '') {
alert('layerId를 설정해 주세요.');
} else {
this.$emit('changeLayerId', layerId);
}
},
closeLayer() {
this.$emit('changeLayerId', '');
},
numberComma(num) {
if (typeof num == undefined || num == null) {
return '';
}
num = num + '';
let point = num.length % 3;
let len = num.length;
let str = num.substring(0, point);
while (point < len) {
if (str != '') {
str += ',';
}
str += num.substring(point, point + 3);
point += 3;
}
return str;
}
}
};
var chkPattern = {
data: function() {
return {};
},
methods: {
setLenth: function(e, len) {
this.cut(e, len);
},
onlyNum: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[0-9]*$/g.exec(str)) {
e.target.value = str.replace(/[^0-9]/gi, '');
}
},
only11Num: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[0-9]*$/g.exec(str)) {
str = str.replace(/[^0-9]/gi, '');
}
if (str.length > 11) {
str = str.substring(0, 11);
}
e.target.value = str;
},
onlyEmail: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[a-zA-Z0-9_\.\-@._-]*$/g.exec(str)) {
e.target.value = str.replace(/[^a-zA-Z0-9_\.\-@._-]/gi, '');
}
},
onlyName: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z]/gi, '');
}
},
onlyTitle: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z0-9]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z0-9]/gi, '');
}
},
onlyText: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z0-9_-]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z0-9_-]/gi, '');
}
},
onlyPassword: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[A-Za-z0-9!@#$%^&*]*$/g.exec(str)) {
e.target.value = str.replace(/[^A-Za-z0-9!@#$%^&*]/gi, '');
}
},
onlyId: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[A-Za-z0-9]*$/g.exec(str)) {
e.target.value = str.replace(/[^A-Za-z0-9]/gi, '');
}
},
onlyIp: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[0-9,.*]*$/g.exec(str)) {
e.target.value = str.replace(/[^0-9,.*]/gi, '');
}
},
onlyRoleNm_Space: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[ㄱ-힣a-zA-Z0-9/\s]*$/g.exec(str)) {
e.target.value = str.replace(/[^ㄱ-힣a-zA-Z0-9/\s]/gi, '');
}
},
onlyRoleId_UnderBar: function(e, len) {
this.cut(e, len);
var str = e.target.value;
if (!/^[a-zA-Z0-9_]*$/g.exec(str)) {
e.target.value = str.replace(/[^a-zA-Z0-9_]/gi, '');
}
},
cut: function(e, len) {
if (typeof len != 'undefined') {
var str = e.target.value;
if (this.bytes(str) > len) {
e.target.value = this.cutBytes(str, len);
}
}
},
cutBytes: function(str, len) {
var count = 0;
for (var i = 0; i < str.length; i++) {
if (escape(str.charAt(i)).length >= 4) count += 2;
else if (escape(str.charAt(i)) != '%0D') count++;
if (count > len) {
if (escape(str.charAt(i)) == '%0A') i--;
break;
}
}
return str.substring(0, i);
},
bytes: function(str) {
var length = 0;
for (var i = 0; i < str.length; i++) {
if (escape(str.charAt(i)).length >= 4) length += 2;
else if (escape(str.charAt(i)) == '%A7') length += 2;
else {
if (escape(str.charAt(i)) != '%0D') length++;
}
}
return length;
},
checkPhone: function(str) {
str = str.replace(/[\-\s\/]+/g, '');
if (str.charAt(0) != '0') {
str = '0' + str;
}
if (str.length < 10 || str.length > 12) {
return '';
}
if (isNaN(str)) {
return '';
}
//if (str.substr(0,2)!="01" && str.substr(0,3)!="070" && str.substr(0,4)!="0505" && str.substr(0,4)!="0503"){return ""; }
//sif (str.substr(0,3)!="010"){return ""; }
return str;
},
checkExcelFile: function(fileObj) {
let reg = /(.*?)\.(xls|xlsx)$/;
if (fileObj == undefined || fileObj == null)
return false;
if (!fileObj.name.match(reg))
return false;
return true;
}
}
};
export { coreUiMixin, chkPattern };

View File

@@ -1,45 +1,45 @@
<template>
<div class="container template_free">
<article id="content" class="content"></article>
<div tabindex="0" class="layer active">
<div tabindex="0" class="layer_cont error">
<div class="layer_body">
<div class="title_wrap center mar_b50">
<h5 class="h5_title" v-html="message">{{ message }}</h5>
</div>
<div class="btn_wrap mar_t20 center">
<a v-for="(branch, index) in branchList" :key="index" href="javascript:void(0);" class="btn mid" :class="branch.class" @click="branch.callback"><span>{{ branch.text }}</span></a>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
/*
branchList: [
{
text: "저장",
class: "bd_black",
callback: callback
},
.....
]
*/
export default {
name: "buttonBranch",
props: {
message: String,
branchList: {
text: Array,
class: String,
callback: Function
}
},
data() {
return {
}
}
}
<template>
<div class="container template_free">
<article id="content" class="content"></article>
<div tabindex="0" class="layer active">
<div tabindex="0" class="layer_cont error">
<div class="layer_body">
<div class="title_wrap center mar_b50">
<h5 class="h5_title" v-html="message">{{ message }}</h5>
</div>
<div class="btn_wrap mar_t20 center">
<a v-for="(branch, index) in branchList" :key="index" href="javascript:void(0);" class="btn mid" :class="branch.class" @click="branch.callback"><span>{{ branch.text }}</span></a>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
/*
branchList: [
{
text: "저장",
class: "bd_black",
callback: callback
},
.....
]
*/
export default {
name: "buttonBranch",
props: {
message: String,
branchList: {
text: Array,
class: String,
callback: Function
}
},
data() {
return {
}
}
}
</script>

View File

@@ -1,199 +1,199 @@
<template>
<section>
<!-- <div class="emulator_wrap"> -->
<div class="inner_emul">
<strong class="blind">미리보기</strong>
<div class="emulator_area">
<div class="emulator_cont">
<div class="img_area description">
<img :src="bgImageData" v-if="bgImageData && !retrivebgFlag">
<img :src="this.bgImageUrl" v-else-if="retrivebgFlag">
<img src="@/assets/images/common/img_placeholder02.png" v-else>
</div>
<div class="rcs_profile_area">
<img :src="profileImageData" v-if="profileImageData && !retriveProfileFlag">
<img :src="this.profileImageUrl" v-else-if="retriveProfileFlag">
<img src="@/assets/images/common/img_profile_blank.png" v-else>
</div>
<strong class="rcs_brand_name">{{this.brandInfoData.name}}</strong>
<div class="rcs_icon_area">
<span
v-for="(item, index) in visibleMenuItemList"
:key="index"
class="rcs_icon"
:class="`icon_${item.code.toLowerCase()}`"
></span>
</div>
<div class="rcs_desc_area" v-html="this.brandInfoData.descr"></div>
<div class="rcs_detail_area">
<dl>
<dt>전화번호</dt>
<dd>{{this.brandInfoData.tel}}</dd>
<dt>웹사이트</dt>
<dd>{{this.brandInfoData.url}}</dd>
<dt>이메일</dt>
<dd v-if="this.brandInfoData.email === '@'"></dd>
<dd v-else>{{this.brandInfoData.email}}</dd>
<dt>주소</dt>
<dd>{{this.brandInfoData.addrRegnNo}}{{this.brandInfoData.addrMngNo}}{{this.brandInfoData.addrDtl}}</dd>
</dl>
</div>
</div>
</div>
</div>
<!-- </div> -->
</section>
</template>
<script>
// 스크립트를 정의하는 부분
// 개발자 작업 영역
//import { getImageUrl } from '@/service/code'
// [ECMA6] export default 된 부분이 외부에서 import로 사용할 수 있게 된다.
export default {
// .vue 내부에서 사용되는 model
// model 기반으로 vue는 동작된다.
props: {
brandInfoData: {
type: Object
}
},
data() {
return {
bgImageData: '',
profileImageData: '',
profileImageUrl: '',
bgImageUrl: '',
retriveProfileFlag: false,
retrivebgFlag: false
}
},
created() {
// DOM이 만들어 지기 전 실행 되는 곳
// Data를 사전에 준비할 경우 사용된다.
},
mounted() {
// DOM에 해당 .vue가 들어가게 되면 실행 되는 곳
// onload 상태와 동일하다. DOM 이후에 조작할 경우 이곳에서 수행
},
watch: {
'brandInfoData.descr'() {
this.brandInfoData.descr = this.brandInfoData.descr.replace(/\(|\)|on.*\(|eval\(|javascript/gi,'')
.split('\n')
.join('<br />')
},
'brandInfoData.profileImgFile'() {
if (this.brandInfoData.profileImgFile) {
let reader = new FileReader()
let vm = this
let file = this.brandInfoData.profileImgFile
reader.onload = e => {
vm.profileImageData = e.target.result
}
reader.readAsDataURL(file)
} else {
this.profileImageData = ''
}
},
'brandInfoData.bgImgFile'() {
if (this.brandInfoData.bgImgFile) {
let reader = new FileReader()
let vm = this
let file = this.brandInfoData.bgImgFile
reader.onload = e => {
vm.bgImageData = e.target.result
}
reader.readAsDataURL(file)
} else {
this.bgImageData = ''
}
},
'brandInfoData.profileImgFileId'() {
if (
!jglib.isEmpty(this.brandInfoData.profileImgFileId) &&
!jglib.isEmpty(this.brandInfoData.profileImgFileNo)
) {
this.retriveProfileFlag = true
let reqObj = {
fileId: this.brandInfoData.profileImgFileId,
fileNo: this.brandInfoData.profileImgFileNo
}
getImageUrl(reqObj).then(res => {
this.profileImageUrl = res.downloadUrl
})
} else {
this.retriveProfileFlag = false
this.profileImageUrl = ''
}
},
'brandInfoData.bgImgFileId'() {
if (
!jglib.isEmpty(this.brandInfoData.bgImgFileId) &&
!jglib.isEmpty(this.brandInfoData.bgImgFileNo)
) {
this.retrivebgFlag = true
let reqObj = {
fileId: this.brandInfoData.bgImgFileId,
fileNo: this.brandInfoData.bgImgFileNo
}
getImageUrl(reqObj).then(res => {
this.bgImageUrl = res.downloadUrl
})
} else {
this.retrivebgFlag = false
this.bgImageUrl = ''
}
}
},
computed: {
// 값이 자주 변경됨에 따라, 관련되어 데이터 혹은 view가 바뀌어야 할 경우 사용
// method를 바로 연결하면 tic 단위로 계속 실행되기 때문에, 값이 변경할 때만 수행되고,
// cache로 남는 computed를 활용하는 것이 성능에 좋음
visibleMenuItemList() {
if (this.brandInfoData.menuItemList) {
return this.brandInfoData.menuItemList.filter(res => {
return res.visible
})
} else {
return []
}
}
},
methods: {
// .vue 내부에서 사용되는 함수를 정의한다.
// 이벤트에 따라 실행하거나, 내부적으로 사용되는 함수들을 정의한다.
getImageUrl: function(reqData) {
if (!isUseAPI()) {
return new Promise((resolve, reject) => {
let res = {
code: '99999999',
msg: 'not available in mockup'
}
resolve(res)
})
}
return new Promise((resolve, reject) => {
request({
url: `/file/${reqData.fileId}/${reqData.fileNo}`,
method: 'get'
})
.then(res => {
let imgData = {
fileName: res.result.fileName,
downloadUrl: res.result.downloadUrl
}
resolve(imgData)
})
.catch(res => {
reject('error in filedownload')
})
})
}
}
}
</script>
<template>
<section>
<!-- <div class="emulator_wrap"> -->
<div class="inner_emul">
<strong class="blind">미리보기</strong>
<div class="emulator_area">
<div class="emulator_cont">
<div class="img_area description">
<img :src="bgImageData" v-if="bgImageData && !retrivebgFlag">
<img :src="this.bgImageUrl" v-else-if="retrivebgFlag">
<img src="@/assets/images/common/img_placeholder02.png" v-else>
</div>
<div class="rcs_profile_area">
<img :src="profileImageData" v-if="profileImageData && !retriveProfileFlag">
<img :src="this.profileImageUrl" v-else-if="retriveProfileFlag">
<img src="@/assets/images/common/img_profile_blank.png" v-else>
</div>
<strong class="rcs_brand_name">{{this.brandInfoData.name}}</strong>
<div class="rcs_icon_area">
<span
v-for="(item, index) in visibleMenuItemList"
:key="index"
class="rcs_icon"
:class="`icon_${item.code.toLowerCase()}`"
></span>
</div>
<div class="rcs_desc_area" v-html="this.brandInfoData.descr"></div>
<div class="rcs_detail_area">
<dl>
<dt>전화번호</dt>
<dd>{{this.brandInfoData.tel}}</dd>
<dt>웹사이트</dt>
<dd>{{this.brandInfoData.url}}</dd>
<dt>이메일</dt>
<dd v-if="this.brandInfoData.email === '@'"></dd>
<dd v-else>{{this.brandInfoData.email}}</dd>
<dt>주소</dt>
<dd>{{this.brandInfoData.addrRegnNo}}{{this.brandInfoData.addrMngNo}}{{this.brandInfoData.addrDtl}}</dd>
</dl>
</div>
</div>
</div>
</div>
<!-- </div> -->
</section>
</template>
<script>
// 스크립트를 정의하는 부분
// 개발자 작업 영역
//import { getImageUrl } from '@/service/code'
// [ECMA6] export default 된 부분이 외부에서 import로 사용할 수 있게 된다.
export default {
// .vue 내부에서 사용되는 model
// model 기반으로 vue는 동작된다.
props: {
brandInfoData: {
type: Object
}
},
data() {
return {
bgImageData: '',
profileImageData: '',
profileImageUrl: '',
bgImageUrl: '',
retriveProfileFlag: false,
retrivebgFlag: false
}
},
created() {
// DOM이 만들어 지기 전 실행 되는 곳
// Data를 사전에 준비할 경우 사용된다.
},
mounted() {
// DOM에 해당 .vue가 들어가게 되면 실행 되는 곳
// onload 상태와 동일하다. DOM 이후에 조작할 경우 이곳에서 수행
},
watch: {
'brandInfoData.descr'() {
this.brandInfoData.descr = this.brandInfoData.descr.replace(/\(|\)|on.*\(|eval\(|javascript/gi,'')
.split('\n')
.join('<br />')
},
'brandInfoData.profileImgFile'() {
if (this.brandInfoData.profileImgFile) {
let reader = new FileReader()
let vm = this
let file = this.brandInfoData.profileImgFile
reader.onload = e => {
vm.profileImageData = e.target.result
}
reader.readAsDataURL(file)
} else {
this.profileImageData = ''
}
},
'brandInfoData.bgImgFile'() {
if (this.brandInfoData.bgImgFile) {
let reader = new FileReader()
let vm = this
let file = this.brandInfoData.bgImgFile
reader.onload = e => {
vm.bgImageData = e.target.result
}
reader.readAsDataURL(file)
} else {
this.bgImageData = ''
}
},
'brandInfoData.profileImgFileId'() {
if (
!jglib.isEmpty(this.brandInfoData.profileImgFileId) &&
!jglib.isEmpty(this.brandInfoData.profileImgFileNo)
) {
this.retriveProfileFlag = true
let reqObj = {
fileId: this.brandInfoData.profileImgFileId,
fileNo: this.brandInfoData.profileImgFileNo
}
getImageUrl(reqObj).then(res => {
this.profileImageUrl = res.downloadUrl
})
} else {
this.retriveProfileFlag = false
this.profileImageUrl = ''
}
},
'brandInfoData.bgImgFileId'() {
if (
!jglib.isEmpty(this.brandInfoData.bgImgFileId) &&
!jglib.isEmpty(this.brandInfoData.bgImgFileNo)
) {
this.retrivebgFlag = true
let reqObj = {
fileId: this.brandInfoData.bgImgFileId,
fileNo: this.brandInfoData.bgImgFileNo
}
getImageUrl(reqObj).then(res => {
this.bgImageUrl = res.downloadUrl
})
} else {
this.retrivebgFlag = false
this.bgImageUrl = ''
}
}
},
computed: {
// 값이 자주 변경됨에 따라, 관련되어 데이터 혹은 view가 바뀌어야 할 경우 사용
// method를 바로 연결하면 tic 단위로 계속 실행되기 때문에, 값이 변경할 때만 수행되고,
// cache로 남는 computed를 활용하는 것이 성능에 좋음
visibleMenuItemList() {
if (this.brandInfoData.menuItemList) {
return this.brandInfoData.menuItemList.filter(res => {
return res.visible
})
} else {
return []
}
}
},
methods: {
// .vue 내부에서 사용되는 함수를 정의한다.
// 이벤트에 따라 실행하거나, 내부적으로 사용되는 함수들을 정의한다.
getImageUrl: function(reqData) {
if (!isUseAPI()) {
return new Promise((resolve, reject) => {
let res = {
code: '99999999',
msg: 'not available in mockup'
}
resolve(res)
})
}
return new Promise((resolve, reject) => {
request({
url: `/file/${reqData.fileId}/${reqData.fileNo}`,
method: 'get'
})
.then(res => {
let imgData = {
fileName: res.result.fileName,
downloadUrl: res.result.downloadUrl
}
resolve(imgData)
})
.catch(res => {
reject('error in filedownload')
})
})
}
}
}
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -1,139 +1,139 @@
.rtl {
direction: rtl;
}
.vdp-datepicker {
position: relative;
text-align: left;
}
.vdp-datepicker * {
box-sizing: border-box;
}
.vdp-datepicker__calendar {
position: absolute;
z-index: 100;
background: #fff;
width: 300px;
border: 1px solid #ccc;
}
.vdp-datepicker__calendar header {
display: block;
line-height: 40px;
}
.vdp-datepicker__calendar header span {
display: inline-block;
text-align: center;
width: 71.42857142857143%;
float: left;
}
.vdp-datepicker__calendar header .prev,
.vdp-datepicker__calendar header .next {
width: 14.285714285714286%;
float: left;
text-indent: -10000px;
position: relative;
}
.vdp-datepicker__calendar header .prev:after,
.vdp-datepicker__calendar header .next:after {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
border: 6px solid transparent;
}
.vdp-datepicker__calendar header .prev:after {
border-right: 10px solid #000;
margin-left: -5px;
}
.vdp-datepicker__calendar header .prev.disabled:after {
border-right: 10px solid #ddd;
}
.vdp-datepicker__calendar header .next:after {
border-left: 10px solid #000;
margin-left: 5px;
}
.vdp-datepicker__calendar header .next.disabled:after {
border-left: 10px solid #ddd;
}
.vdp-datepicker__calendar header .prev:not(.disabled),
.vdp-datepicker__calendar header .next:not(.disabled),
.vdp-datepicker__calendar header .up:not(.disabled) {
cursor: pointer;
}
.vdp-datepicker__calendar header .prev:not(.disabled):hover,
.vdp-datepicker__calendar header .next:not(.disabled):hover,
.vdp-datepicker__calendar header .up:not(.disabled):hover {
background: #eee;
}
.vdp-datepicker__calendar .disabled {
color: #ddd;
cursor: default;
}
.vdp-datepicker__calendar .flex-rtl {
display: flex;
width: inherit;
flex-wrap: wrap;
}
.vdp-datepicker__calendar .cell {
display: inline-block;
padding: 0 5px;
width: 14.285714285714286%;
height: 40px;
line-height: 40px;
text-align: center;
vertical-align: middle;
border: 1px solid transparent;
}
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year {
cursor: pointer;
}
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day:hover,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month:hover,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year:hover {
border: 1px solid #4bd;
}
.vdp-datepicker__calendar .cell.selected {
background: #4bd;
}
.vdp-datepicker__calendar .cell.selected:hover {
background: #4bd;
}
.vdp-datepicker__calendar .cell.selected.highlighted {
background: #4bd;
}
.vdp-datepicker__calendar .cell.highlighted {
background: #cae5ed;
}
.vdp-datepicker__calendar .cell.highlighted.disabled {
color: #a3a3a3;
}
.vdp-datepicker__calendar .cell.grey {
color: #888;
}
.vdp-datepicker__calendar .cell.grey:hover {
background: inherit;
}
.vdp-datepicker__calendar .cell.day-header {
font-size: 75%;
white-space: nowrap;
cursor: inherit;
}
.vdp-datepicker__calendar .cell.day-header:hover {
background: inherit;
}
.vdp-datepicker__calendar .month,
.vdp-datepicker__calendar .year {
width: 33.333%;
}
.vdp-datepicker__clear-button,
.vdp-datepicker__calendar-button {
cursor: pointer;
font-style: normal;
}
.vdp-datepicker__clear-button.disabled,
.vdp-datepicker__calendar-button.disabled {
color: #999;
cursor: default;
}
.rtl {
direction: rtl;
}
.vdp-datepicker {
position: relative;
text-align: left;
}
.vdp-datepicker * {
box-sizing: border-box;
}
.vdp-datepicker__calendar {
position: absolute;
z-index: 100;
background: #fff;
width: 300px;
border: 1px solid #ccc;
}
.vdp-datepicker__calendar header {
display: block;
line-height: 40px;
}
.vdp-datepicker__calendar header span {
display: inline-block;
text-align: center;
width: 71.42857142857143%;
float: left;
}
.vdp-datepicker__calendar header .prev,
.vdp-datepicker__calendar header .next {
width: 14.285714285714286%;
float: left;
text-indent: -10000px;
position: relative;
}
.vdp-datepicker__calendar header .prev:after,
.vdp-datepicker__calendar header .next:after {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
border: 6px solid transparent;
}
.vdp-datepicker__calendar header .prev:after {
border-right: 10px solid #000;
margin-left: -5px;
}
.vdp-datepicker__calendar header .prev.disabled:after {
border-right: 10px solid #ddd;
}
.vdp-datepicker__calendar header .next:after {
border-left: 10px solid #000;
margin-left: 5px;
}
.vdp-datepicker__calendar header .next.disabled:after {
border-left: 10px solid #ddd;
}
.vdp-datepicker__calendar header .prev:not(.disabled),
.vdp-datepicker__calendar header .next:not(.disabled),
.vdp-datepicker__calendar header .up:not(.disabled) {
cursor: pointer;
}
.vdp-datepicker__calendar header .prev:not(.disabled):hover,
.vdp-datepicker__calendar header .next:not(.disabled):hover,
.vdp-datepicker__calendar header .up:not(.disabled):hover {
background: #eee;
}
.vdp-datepicker__calendar .disabled {
color: #ddd;
cursor: default;
}
.vdp-datepicker__calendar .flex-rtl {
display: flex;
width: inherit;
flex-wrap: wrap;
}
.vdp-datepicker__calendar .cell {
display: inline-block;
padding: 0 5px;
width: 14.285714285714286%;
height: 40px;
line-height: 40px;
text-align: center;
vertical-align: middle;
border: 1px solid transparent;
}
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year {
cursor: pointer;
}
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).day:hover,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).month:hover,
.vdp-datepicker__calendar .cell:not(.blank):not(.disabled).year:hover {
border: 1px solid #4bd;
}
.vdp-datepicker__calendar .cell.selected {
background: #4bd;
}
.vdp-datepicker__calendar .cell.selected:hover {
background: #4bd;
}
.vdp-datepicker__calendar .cell.selected.highlighted {
background: #4bd;
}
.vdp-datepicker__calendar .cell.highlighted {
background: #cae5ed;
}
.vdp-datepicker__calendar .cell.highlighted.disabled {
color: #a3a3a3;
}
.vdp-datepicker__calendar .cell.grey {
color: #888;
}
.vdp-datepicker__calendar .cell.grey:hover {
background: inherit;
}
.vdp-datepicker__calendar .cell.day-header {
font-size: 75%;
white-space: nowrap;
cursor: inherit;
}
.vdp-datepicker__calendar .cell.day-header:hover {
background: inherit;
}
.vdp-datepicker__calendar .month,
.vdp-datepicker__calendar .year {
width: 33.333%;
}
.vdp-datepicker__clear-button,
.vdp-datepicker__calendar-button {
cursor: pointer;
font-style: normal;
}
.vdp-datepicker__clear-button.disabled,
.vdp-datepicker__calendar-button.disabled {
color: #999;
cursor: default;
}

View File

@@ -1,25 +1,25 @@
<template>
<footer class="footer-wrap">
<div class="footer div-cont">
<div class="f-logo"><a href="/"><img src="../assets/images/flogo.png" alt=""></a></div>
<div class="f-info">
<ul>
<li><p>()엘지유플러스</p></li>
<li><p>주소 서울특별시 용산구 한강대로 32</p></li>
</ul>
<ul>
<li><p>대표이사 황현식</p></li>
<li><p>사업자번호 220-81-39938</p></li>
<li><p>통신판매신고 제2010-서울중구-0968</p></li>
<li><p>고객센터 1544-5992</p></li>
<li><p>e-Mail <a href="mailto:smshelp@lguplus.co.kr">smshelp@lguplus.co.kr</a></p></li>
</ul>
<p>Copyright © LG Uplus Corp. All Rights Reserved.</p>
</div>
</div>
</footer>
</template>
<script>
</script>
<template>
<footer class="footer-wrap">
<div class="footer div-cont">
<div class="f-logo"><a href="/"><img src="../assets/images/flogo.png" alt=""></a></div>
<div class="f-info">
<ul>
<li><p>()엘지유플러스</p></li>
<li><p>주소 서울특별시 용산구 한강대로 32</p></li>
</ul>
<ul>
<li><p>대표이사 황현식</p></li>
<li><p>사업자번호 220-81-39938</p></li>
<li><p>통신판매신고 제2010-서울중구-0968</p></li>
<li><p>고객센터 1544-5992</p></li>
<li><p>e-Mail <a href="mailto:smshelp@lguplus.co.kr">smshelp@lguplus.co.kr</a></p></li>
</ul>
<p>Copyright © LG Uplus Corp. All Rights Reserved.</p>
</div>
</div>
</footer>
</template>
<script>
</script>

View File

@@ -1,87 +1,87 @@
<template>
<header>
<h1 class="logo"><a href="javascript:void(0)">uplus 메시지허브이지<span>BACKOFFICE</span></a></h1>
<div class="user_wrap">
<div class="user" @click="userInfoToggle();">
<p>슈퍼관리자</p>
<a href="javascript:void(0)" class="btn_user">Uplus01</a>
</div>
<div class="user_info">
<a href="superadmin_info.html" class="modify">정보수정</a>
<a href="javascript:void(0)" class="logout" @click="logout();">로그아웃</a>
</div>
</div>
</header>
</template>
<script>
//import tokenSvc from '@/common/token-service';
import { mapGetters } from 'vuex';
import loginApi from '@/modules/login/service/api';
export default {
name: "hubWebHeader",
data() {
return {
menuList: null,
isLogin: false,
isErrPage: false,
navActive: false,
}
},
created() {
},
computed: {
...mapGetters({
getLogin: 'login/isLogin',
getErrorPage: 'login/isErrorPage',
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
//this.setMenuData();
} else {
this.isLogin = false;
//this.menuList = null;
}
},
getErrorPage(data) {
if (data != null && data != '' && data == true) {
this.isErrPage = true;
} else {
this.isErrPage = false;
}
},
},
methods: {
userInfoToggle(){
var click = "clicked";
var userBtn = document.querySelector('.user_wrap .user');
if(userBtn.classList.contains(click)){
userBtn.classList.remove(click);
}
else{
userBtn.classList.add(click);
}
},
logout(){
let result = confirm("로그아웃 하시겠습니까?");
if (result) {
loginApi.logout().then(response => {
if(response.data.retCode == '0000'){
//tokenSvc.removeToken();
this.$router.push({
path: "/login"
});
}
});
}
}
}
};
</script>
<template>
<header>
<h1 class="logo"><a href="javascript:void(0)">uplus 메시지허브이지<span>BACKOFFICE</span></a></h1>
<div class="user_wrap">
<div class="user" @click="userInfoToggle();">
<p>슈퍼관리자</p>
<a href="javascript:void(0)" class="btn_user">Uplus01</a>
</div>
<div class="user_info">
<a href="superadmin_info.html" class="modify">정보수정</a>
<a href="javascript:void(0)" class="logout" @click="logout();">로그아웃</a>
</div>
</div>
</header>
</template>
<script>
//import tokenSvc from '@/common/token-service';
import { mapGetters } from 'vuex';
import loginApi from '@/modules/login/service/api';
export default {
name: "hubWebHeader",
data() {
return {
menuList: null,
isLogin: false,
isErrPage: false,
navActive: false,
}
},
created() {
},
computed: {
...mapGetters({
getLogin: 'login/isLogin',
getErrorPage: 'login/isErrorPage',
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
//this.setMenuData();
} else {
this.isLogin = false;
//this.menuList = null;
}
},
getErrorPage(data) {
if (data != null && data != '' && data == true) {
this.isErrPage = true;
} else {
this.isErrPage = false;
}
},
},
methods: {
userInfoToggle(){
var click = "clicked";
var userBtn = document.querySelector('.user_wrap .user');
if(userBtn.classList.contains(click)){
userBtn.classList.remove(click);
}
else{
userBtn.classList.add(click);
}
},
logout(){
let result = confirm("로그아웃 하시겠습니까?");
if (result) {
loginApi.logout().then(response => {
if(response.data.retCode == '0000'){
//tokenSvc.removeToken();
this.$router.push({
path: "/login"
});
}
});
}
}
}
};
</script>

View File

@@ -1,56 +1,56 @@
<template>
<div>
<div>role: {{role}}</div><br/>
<TreeMenu :nodes="tree.nodes" :depth="0" :label="tree.label"></TreeMenu>
</div>
</template>
<script>
import TreeMenu from './TreeMenu';
import tokenSvc from '@/common/token-service';
let tree = {
label: 'root',
nodes: [
{
label: 'item1',
nodes: [
{
label: 'item1.1'
},
{
label: 'item1.2',
nodes: [
{
label: 'item1.2.1'
}
]
}
]
},
{
label: 'item2'
}
]
};
export default {
components: {
TreeMenu
},
data() {
return {
tree
};
},
computed: {
role() {
return tokenSvc.getToken().principal.authorities[0].authority;
}
},
created() {
console.log('created Lnb');
console.log('node[0]:', this.tree.nodes[0].label);
console.log('role:', tokenSvc.getToken().principal.authorities[0].authority);
}
};
</script>
<template>
<div>
<div>role: {{role}}</div><br/>
<TreeMenu :nodes="tree.nodes" :depth="0" :label="tree.label"></TreeMenu>
</div>
</template>
<script>
import TreeMenu from './TreeMenu';
import tokenSvc from '@/common/token-service';
let tree = {
label: 'root',
nodes: [
{
label: 'item1',
nodes: [
{
label: 'item1.1'
},
{
label: 'item1.2',
nodes: [
{
label: 'item1.2.1'
}
]
}
]
},
{
label: 'item2'
}
]
};
export default {
components: {
TreeMenu
},
data() {
return {
tree
};
},
computed: {
role() {
return tokenSvc.getToken().principal.authorities[0].authority;
}
},
created() {
console.log('created Lnb');
console.log('node[0]:', this.tree.nodes[0].label);
console.log('role:', tokenSvc.getToken().principal.authorities[0].authority);
}
};
</script>

View File

@@ -1,307 +1,308 @@
<template>
<!-- 버튼 -->
<div class="wrap bg-wrap">
<!-- <div class="popup-btn-wrap">
<button class="trigger" onclick="ModalOpen('modal01');">로그인실패: 확인</button>
<button class="trigger" onclick="ModalOpen('modal02');">로그인실패: 5</button>
<button class="trigger" onclick="ModalOpen('modal03');">로그인실패: 상태</button>
<button class="trigger" onclick="ModalOpen('modal04');">보안 알림</button>
<button class="trigger" onclick="ModalOpen('modal05');">중복 로그인</button>
<button class="trigger" onclick="ModalOpen('modal06');">휴대폰번호 확인</button>
<button class="trigger" onclick="ModalOpen('modal07');">인증번호: 발송</button>
<button class="trigger" onclick="ModalOpen('modal08');">인증번호: 입력</button>
<button class="trigger" onclick="ModalOpen('modal09');">인증실패: 인증번호</button>
<button class="trigger" onclick="ModalOpen('modal10');">인증실패: 시간초과</button>
<button class="trigger" onclick="ModalOpen('modal11');">인증실패: 5</button>
<button class="trigger" onclick="ModalOpen('modal12');">비밀번호 초기화 문자 발송</button>
<button class="trigger" onclick="ModalOpen('modal13');">아이디 오류</button>
<button class="trigger" onclick="ModalOpen('modal14');">비밀번호 오류</button>
<button class="trigger" onclick="ModalOpen('modal15');">비밀번호 패턴 오류</button>
<button class="trigger" onclick="ModalOpen('modal16');">비밀번호 정상 변경</button>
</div> -->
<!-- s: 팝업 -->
<div class="dimmed" @click="ModalClose();"></div>
<div class="popup-wrap">
<!-- 로그인실패: 확인 -->
<div class="popup modal01">
<div class="pop-head">
<h3 class="pop-tit">로그인 실패</h3>
</div>
<div class="pop-cont">
<p>아이디,비밀번호를 확인해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 로그인실패: 5회 -->
<div class="popup modal02">
<div class="pop-head">
<h3 class="pop-tit">로그인 실패</h3>
</div>
<div class="pop-cont">
<p>로그인 5 실패하였습니다.</p>
<p>비밀번호 초기화 비밀번호를 변경해 주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 로그인실패: 상태 -->
<div class="popup modal03">
<div class="pop-head">
<h3 class="pop-tit">로그인 실패</h3>
</div>
<div class="pop-cont">
<p>아이디 상태를 확인해 주세요.</p>
<p>(사용중인 상태만 로그인 가능합니다.)</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 보안 알림 -->
<div class="popup modal04">
<div class="pop-head">
<h3 class="pop-tit">보안 알림</h3>
</div>
<div class="pop-cont">
<p>비밀번호를 변경하지 않은지 90일이</p>
<p>지났습니다. 비밀번호를 변경하여</p>
<p>이용 부탁드립니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">비밀번호 변경하기</button>
</div>
</div>
<!-- 중복 로그인 -->
<div class="popup modal05">
<div class="pop-head">
<h3 class="pop-tit">중복 로그인</h3>
</div>
<div class="pop-cont">
<p>동일한 아이디로 로그인 되어 있습니다.</p>
<p>이전 로그인 세션 종료 로그인하시겠습니까?</p>
<p>확인 이전 로그인한 상태는 로그아웃됩니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 휴대폰번호 확인 -->
<div class="popup modal06">
<div class="pop-head">
<h3 class="pop-tit">휴대폰번호 확인</h3>
</div>
<div class="pop-cont">
<p>휴대폰번호를 확인해주세요.</p>
<p>아이디에 등록된 휴대폰번호로만 인증이 가능합니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증번호: 발송 -->
<div class="popup modal07">
<div class="pop-head">
<h3 class="pop-tit">인증번호 발송</h3>
</div>
<div class="pop-cont">
<p>인증번호를 발송하였습니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증번호: 입력 -->
<div class="popup modal08">
<div class="pop-head">
<h3 class="pop-tit">인증번호 입력</h3>
</div>
<div class="pop-cont">
<p>인증번호를 입력하세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증실패: 인증번호 -->
<div class="popup modal09">
<div class="pop-head">
<h3 class="pop-tit">인증실패</h3>
</div>
<div class="pop-cont">
<p>잘못된 인증번호입니다.</p>
<p>5 실패 로그아웃됩니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증실패: 시간초과 -->
<div class="popup modal10">
<div class="pop-head">
<h3 class="pop-tit">인증실패</h3>
</div>
<div class="pop-cont">
<p>인증시간 초과되었습니다.</p>
<p>다시 휴대폰번호를 입력해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증실패: 5회 -->
<div class="popup modal11">
<div class="pop-head">
<h3 class="pop-tit">인증실패</h3>
</div>
<div class="pop-cont">
<p>인증번호 5 실패하였습니다.</p>
<p>로그아웃되어 다시 로그인해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 초기화 발송 -->
<div class="popup modal12">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 초기화</h3>
</div>
<div class="pop-cont">
<p>해당 아이디에 저장되어 있는 핸드폰번호로</p>
<p>비밀번호 초기화 문자가 발송되었습니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 아이디 오류 -->
<div class="popup modal13">
<div class="pop-head">
<h3 class="pop-tit">아이디 오류</h3>
</div>
<div class="pop-cont">
<p>등록되지 않은 아이디입니다.</p>
<p>아이디를 다시 확인하세요</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 오류 -->
<div class="popup modal14">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 오류</h3>
</div>
<div class="pop-cont">
<p>비밀번호를 확인해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 패턴 오류 -->
<div class="popup modal15">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 오류</h3>
</div>
<div class="pop-cont">
<p>비밀번호를 사용할 없습니다.</p>
<p>비밀번호는 영문/숫자/특수기호를 혼합하여</p>
<p>8~16자리로 설정해주세요</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 정상 변경 -->
<div class="popup modal16">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 오류</h3>
</div>
<div class="pop-cont">
<p>비밀번호가 정상적으로 변경되었습니다.</p>
<p>변경된 비밀번호로 다시 로그인 해주세요</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
</div>
<!-- e: 팝업 -->
</div>
</template>
<script>
export default {
data(){
return{
}
},
methods: {
//모달 켜기
ModalOpen(target){
console.log("ModalOpen");
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = document.getElementsByClassName(target);
dimmed[0].style.display = 'block';
wrap[0].style.display = 'block';
obj[0].style.display = 'block';
},
// 모달 끄기
ModalClose(){
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = wrap[0].childElementCount
dimmed[0].style.display = 'none';
wrap[0].style.display = 'none';
for(var i = 0; i < obj; i++) {
var target = document.getElementsByClassName('popup');
target[i].style.display = 'none';
}
},
}
}
</script>
<style>
.popup-btn-wrap {width: 500px; margin: auto; padding: 100px 0;}
.popup-btn-wrap button {width: 100%; margin-bottom: 10px; height: 50px; border-radius: 5px; box-shadow: none; border: 1px solid #000; }
.popup-btn-wrap button:hover {background: #000; color: #fff;}
<template>
<!-- 버튼 -->
<div class="wrap bg-wrap">
<!-- <div class="popup-btn-wrap">
<button class="trigger" onclick="ModalOpen('modal01');">로그인실패: 확인</button>
<button class="trigger" onclick="ModalOpen('modal02');">로그인실패: 5</button>
<button class="trigger" onclick="ModalOpen('modal03');">로그인실패: 상태</button>
<button class="trigger" onclick="ModalOpen('modal04');">보안 알림</button>
<button class="trigger" onclick="ModalOpen('modal05');">중복 로그인</button>
<button class="trigger" onclick="ModalOpen('modal06');">휴대폰번호 확인</button>
<button class="trigger" onclick="ModalOpen('modal07');">인증번호: 발송</button>
<button class="trigger" onclick="ModalOpen('modal08');">인증번호: 입력</button>
<button class="trigger" onclick="ModalOpen('modal09');">인증실패: 인증번호</button>
<button class="trigger" onclick="ModalOpen('modal10');">인증실패: 시간초과</button>
<button class="trigger" onclick="ModalOpen('modal11');">인증실패: 5</button>
<button class="trigger" onclick="ModalOpen('modal12');">비밀번호 초기화 문자 발송</button>
<button class="trigger" onclick="ModalOpen('modal13');">아이디 오류</button>
<button class="trigger" onclick="ModalOpen('modal14');">비밀번호 오류</button>
<button class="trigger" onclick="ModalOpen('modal15');">비밀번호 패턴 오류</button>
<button class="trigger" onclick="ModalOpen('modal16');">비밀번호 정상 변경</button>
</div> -->
<!-- s: 팝업 -->
<div class="dimmed" @click="ModalClose();"></div>
<div class="popup-wrap">
<!-- 로그인실패: 확인 -->
<div class="popup modal01">
<div class="pop-head">
<h3 class="pop-tit">로그인 실패</h3>
</div>
<div class="pop-cont">
<p>아이디,비밀번호를 확인해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 로그인실패: 5회 -->
<div class="popup modal02">
<div class="pop-head">
<h3 class="pop-tit">로그인 실패</h3>
</div>
<div class="pop-cont">
<p>로그인 5 실패하였습니다.</p>
<p>비밀번호 초기화 비밀번호를 변경해 주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 로그인실패: 상태 -->
<div class="popup modal03">
<div class="pop-head">
<h3 class="pop-tit">로그인 실패</h3>
</div>
<div class="pop-cont">
<p>아이디 상태를 확인해 주세요.</p>
<p>(사용중인 상태만 로그인 가능합니다.)</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 보안 알림 -->
<div class="popup modal04">
<div class="pop-head">
<h3 class="pop-tit">보안 알림</h3>
</div>
<div class="pop-cont">
<p>비밀번호를 변경하지 않은지 90일이</p>
<p>지났습니다. 비밀번호를 변경하여</p>
<p>이용 부탁드립니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="$router.push({ path: '/view/login/updatePassword' })">비밀번호 변경하기</button>
</div>
</div>
<!-- 중복 로그인 -->
<div class="popup modal05">
<div class="pop-head">
<h3 class="pop-tit">중복 로그인</h3>
</div>
<div class="pop-cont">
<p>동일한 아이디로 로그인 되어 있습니다.</p>
<p>이전 로그인 세션 종료 로그인하시겠습니까?</p>
<p>확인 이전 로그인한 상태는 로그아웃됩니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 휴대폰번호 확인 -->
<div class="popup modal06">
<div class="pop-head">
<h3 class="pop-tit">휴대폰번호 확인</h3>
</div>
<div class="pop-cont">
<p>휴대폰번호를 확인해주세요.</p>
<p>아이디에 등록된 휴대폰번호로만 인증이 가능합니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증번호: 발송 -->
<div class="popup modal07">
<div class="pop-head">
<h3 class="pop-tit">인증번호 발송</h3>
</div>
<div class="pop-cont">
<p>인증번호를 발송하였습니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증번호: 입력 -->
<div class="popup modal08">
<div class="pop-head">
<h3 class="pop-tit">인증번호 입력</h3>
</div>
<div class="pop-cont">
<p>인증번호를 입력하세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증실패: 인증번호 -->
<div class="popup modal09">
<div class="pop-head">
<h3 class="pop-tit">인증실패</h3>
</div>
<div class="pop-cont">
<p>잘못된 인증번호입니다.</p>
<p>5 실패 로그아웃됩니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증실패: 시간초과 -->
<div class="popup modal10">
<div class="pop-head">
<h3 class="pop-tit">인증실패</h3>
</div>
<div class="pop-cont">
<p>인증시간 초과되었습니다.</p>
<p>다시 휴대폰번호를 입력해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 인증실패: 5회 -->
<div class="popup modal11">
<div class="pop-head">
<h3 class="pop-tit">인증실패</h3>
</div>
<div class="pop-cont">
<p>인증번호 5 실패하였습니다.</p>
<p>로그아웃되어 다시 로그인해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="$router.go(-1)">확인</button>
</div>
</div>
<!-- 비밀번호 초기화 발송 -->
<div class="popup modal12">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 초기화</h3>
</div>
<div class="pop-cont">
<p>해당 아이디에 저장되어 있는 핸드폰번호로</p>
<p>비밀번호 초기화 문자가 발송되었습니다.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 아이디 오류 -->
<div class="popup modal13">
<div class="pop-head">
<h3 class="pop-tit">아이디 오류</h3>
</div>
<div class="pop-cont">
<p>등록되지 않은 아이디입니다.</p>
<p>아이디를 다시 확인하세요</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 오류 -->
<div class="popup modal14">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 오류</h3>
</div>
<div class="pop-cont">
<p>비밀번호를 확인해주세요.</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 패턴 오류 -->
<div class="popup modal15">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 오류</h3>
</div>
<div class="pop-cont">
<p>비밀번호를 사용할 없습니다.</p>
<p>비밀번호는 영문/숫자/특수기호를 혼합하여</p>
<p>8~16자리로 설정해주세요</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="ModalClose();">확인</button>
</div>
</div>
<!-- 비밀번호 정상 변경 -->
<div class="popup modal16">
<div class="pop-head">
<h3 class="pop-tit">비밀번호 오류</h3>
</div>
<div class="pop-cont">
<p>비밀번호가 정상적으로 변경되었습니다.</p>
<p>변경된 비밀번호로 다시 로그인 해주세요</p>
</div>
<div class="pop-btn1">
<button class="btn-pcolor" @click="$router.go(-1)">확인</button>
</div>
</div>
</div>
<!-- e: 팝업 -->
</div>
</template>
<script>
export default {
data(){
return{
}
},
methods: {
//모달 켜기
ModalOpen(target){
console.log("ModalOpen");
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = document.getElementsByClassName(target);
dimmed[0].style.display = 'block';
wrap[0].style.display = 'block';
obj[0].style.display = 'block';
},
// 모달 끄기
ModalClose(){
var dimmed = document.getElementsByClassName('dimmed');
var wrap = document.getElementsByClassName('popup-wrap');
var obj = wrap[0].childElementCount
dimmed[0].style.display = 'none';
wrap[0].style.display = 'none';
for(var i = 0; i < obj; i++) {
var target = document.getElementsByClassName('popup');
target[i].style.display = 'none';
}
},
}
}
</script>
<style>
.popup-btn-wrap {width: 500px; margin: auto; padding: 100px 0;}
.popup-btn-wrap button {width: 100%; margin-bottom: 10px; height: 50px; border-radius: 5px; box-shadow: none; border: 1px solid #000; }
.popup-btn-wrap button:hover {background: #000; color: #fff;}
</style>

View File

@@ -1,132 +1,121 @@
<template>
<nav>
<ul v-if="menuList.length > 0" class="main_menu">
<!-- 선택한 메뉴 li.is-current -->
<li v-for="child in menuList" :key="child.menuNo" :class="child.classNm">
<div class="menu_btn" ></div>
<a class="menu_target" @click="clickTest" :data-menu-no="child.menuNo">{{child.menuNm}}</a>
<div class="sub_menu_wrap">
<ul class="sub_menu" v-if="child.children.length > 0">
<li v-for="child2 in child.children" :key="child2.menuNo">
<a href="javascript:void(0);" @click="clickMenu(child2.menuUrl)" :data-menu-no="child2.menuNo">{{child2.menuNm}}</a>
</li>
</ul>
</div>
</li>
</ul>
</nav>
</template>
<script>
//import "../assets/js/script.js";
import api from '@/service/api.js';
export default {
name: 'Nav',
props: {
},
data() {
return {
isLogin : false,
isAuthChk : false,
menuList: null,
tempList: null
}
},
created() {
// 메뉴 가져오기
this.setMenuData();
},
mounted() {},
computed: {
},
watch: {
},
methods: {
setMenuData() {
api.menus().then(response => {
const rootMenu = response.data.data;
console.log(rootMenu);
if (rootMenu != null && rootMenu.children != null && rootMenu.children.length > 0) {
this.tempList = rootMenu.children;
for(var i=0; i<this.tempList.length; i++){
var menuNo = this.tempList[i].menuNo;
var classNm = '';
switch(menuNo){
case 1001 : classNm = 'customer'; break;
case 1002 : classNm = 'attract'; break;
case 1003 : classNm = 'service'; break;
case 1004 : classNm = 'calculate'; break;
case 1005 : classNm = 'channel'; break;
case 1006 : classNm = 'key'; break;
case 1007 : classNm = 'moniter'; break;
case 1008 : classNm = 'risk'; break;
case 1009 : classNm = 'stats'; break;
case 1010 : classNm = 'system'; break;
default : classNm = 'customer';
}
this.tempList[i].classNm = classNm;
//console.log(classNm);
}
//this.menuList = rootMenu.children;
this.menuList = this.tempList;
//this.$store.commit("login/isLogin", true);
//this.$store.commit("login/isAuthChk", true);
} else {
this.$store.commit("login/isLogin", false);
this.$store.commit("login/isAuthChk", false);
this.menuList = null;
this.$router.push({ path: '/login' });
}
}).catch(response => {
this.$store.commit("login/isLogin", false);
this.$store.commit("login/isAuthChk", false);
this.menuList = null;
this.$router.push({ path: '/login' });
console.log(response);
});
},
clickMenu(link){
this.$router.push({
path: link
});
},
clickTest(e){
const menuList = document.querySelectorAll('.main_menu .is-current');
if(e.target.classList.contains('menu_target') || e.target.classList.contains('menu_btn')){
const menuListCheck = e.target.parentNode;
if(menuListCheck.classList.contains('is-current')){
menuListCheck.classList.remove('is-current');
for(const menu of menuList){
menu.classList.remove('is-current');
}
} else {
for(const other of menuList){
other.classList.remove('is-current');
}
menuListCheck.classList.add('is-current');
}
}
},
}
}
<template>
<nav>
<ul v-if="menuList.length > 0" class="main_menu">
<!-- 선택한 메뉴 li.is-current -->
<li v-for="child in menuList" :key="child.menuNo" :class="child.classNm">
<div class="menu_btn" ></div>
<a class="menu_target" @click="actionMenu" :data-menu-no="child.menuNo">{{child.menuNm}}</a>
<div class="sub_menu_wrap">
<ul class="sub_menu" v-if="child.children.length > 0">
<li v-for="child2 in child.children" :key="child2.menuNo">
<a href="javascript:void(0);" @click="clickMenu(child2.menuUrl)" :data-menu-no="child2.menuNo">{{child2.menuNm}}</a>
</li>
</ul>
</div>
</li>
</ul>
</nav>
</template>
<script>
//import "../assets/js/script.js";
import api from '@/service/api.js';
export default {
name: 'Nav',
props: {
},
data() {
return {
isLogin : false,
isAuthChk : false,
menuList: [],
tempList: []
}
},
created() {
// 메뉴 가져오기
this.setMenuData();
},
mounted() {},
computed: {
},
watch: {
},
methods: {
setMenuData() {
api.menus().then(response => {
const rootMenu = response.data.data;
console.log(rootMenu);
if (rootMenu != null && rootMenu.children != null && rootMenu.children.length > 0) {
this.tempList = rootMenu.children;
for(var i=0; i<this.tempList.length; i++){
var menuNo = this.tempList[i].menuNo;
var classNm = '';
switch(menuNo){
case 1001 : classNm = 'customer'; break;
case 1002 : classNm = 'attract'; break;
case 1003 : classNm = 'service'; break;
case 1004 : classNm = 'calculate'; break;
case 1005 : classNm = 'channel'; break;
case 1006 : classNm = 'key'; break;
case 1007 : classNm = 'moniter'; break;
case 1008 : classNm = 'risk'; break;
case 1009 : classNm = 'stats'; break;
case 1010 : classNm = 'system'; break;
default : classNm = 'customer';
}
this.tempList[i].classNm = classNm;
//console.log(classNm);
}
//this.menuList = rootMenu.children;
this.menuList = this.tempList;
//this.$store.commit("login/isLogin", true);
//this.$store.commit("login/isAuthChk", true);
} else {
window.top.location.href = '/';
}
});
},
clickMenu(link){
this.$router.push({
path: link
});
},
actionMenu(e){
const menuList = document.querySelectorAll('.main_menu .is-current');
if(e.target.classList.contains('menu_target') || e.target.classList.contains('menu_btn')){
const menuListCheck = e.target.parentNode;
if(menuListCheck.classList.contains('is-current')){
menuListCheck.classList.remove('is-current');
for(const menu of menuList){
menu.classList.remove('is-current');
}
} else {
for(const other of menuList){
other.classList.remove('is-current');
}
menuListCheck.classList.add('is-current');
}
}
},
}
}
</script>

View File

@@ -1,133 +1,133 @@
<template>
<div class="paging" :class="{className: true}">
<a href="javascript:void(0);" class="btn_arrow first" @click="changePageFirst">처음으로</a>
<a href="javascript:void(0);" class="btn_arrow prev" @click="changeRangePrev">이전으로</a>
<a
href="javascript:void(0);"
v-for="page in visiblePage"
:key="`page-${page}`"
:class="{'active': parseInt(currentPage) === page}"
@click="changePage(page)"
>{{ page }}</a>
<a href="javascript:void(0);" class="btn_arrow next" @click="changeRangeNext">다음으로</a>
<a href="javascript:void(0);" class="btn_arrow last" @click="changePageLast">마지막으로</a>
</div>
</template>
<script>
export default {
name: 'Pagination',
props: {
total: {
type: [Number, String],
default: 0
},
pageSize: {
type: [Number, String],
default: 10
},
currentPage: {
type: [Number, String],
default: 1
},
className: {
type: String,
default: ''
},
rangeMax: {
type: [Number, String],
default: 10
}
},
data() {
return {
range: 0
}
},
created() {},
mounted() {},
computed: {
visiblePage() {
let range = []
for (let i = this.rangeStart; i <= this.rangeEnd; i++) {
range.push(i)
}
return range
},
lastPage() {
return parseInt(this.total) > 0
? Math.ceil(parseInt(this.total) / parseInt(this.pageSize))
: 1
},
rangeStart() {
return parseInt(this.rangeMax) * this.range + 1
},
rangeEnd() {
return parseInt(this.rangeMax) * (this.range + 1) < this.lastPage
? parseInt(this.rangeMax) * (this.range + 1)
: this.lastPage
},
lastRange() {
return parseInt(this.total) > 0
? Math.ceil(
parseInt(this.total) /
(parseInt(this.pageSize) * parseInt(this.rangeMax))
)
: 0
}
},
watch: {
total() {
this.init()
},
currentPage() {
this.setRange()
}
},
methods: {
init() {
this.range = 0
},
setRange() {
this.range = Math.floor(
(parseInt(this.currentPage) - 1) / parseInt(this.rangeMax)
)
},
changePage(page) {
this.$emit('update:currentPage', page)
this.$emit('change', page)
},
changeRangePrev() {
if (this.range > 0) {
this.range -= 1
this.$emit('update:currentPage', this.rangeStart)
this.$emit('change', this.rangeStart)
}
},
changeRangeNext() {
if (this.range < this.lastRange - 1) {
this.range += 1
this.$emit('update:currentPage', this.rangeStart)
this.$emit('change', this.rangeStart)
}
},
changePageFirst() {
this.range = 0
this.$emit('update:currentPage', 1)
this.$emit('change', 1)
},
changePageLast() {
if (parseInt(this.total) > 0) {
this.range = this.lastRange - 1
} else {
this.range = 0
}
this.$emit('update:currentPage', this.lastPage)
this.$emit('change', this.lastPage)
}
}
}
</script>
<style>
</style>
<template>
<div class="paging" :class="{className: true}">
<a href="javascript:void(0);" class="btn_arrow first" @click="changePageFirst">처음으로</a>
<a href="javascript:void(0);" class="btn_arrow prev" @click="changeRangePrev">이전으로</a>
<a
href="javascript:void(0);"
v-for="page in visiblePage"
:key="`page-${page}`"
:class="{'active': parseInt(currentPage) === page}"
@click="changePage(page)"
>{{ page }}</a>
<a href="javascript:void(0);" class="btn_arrow next" @click="changeRangeNext">다음으로</a>
<a href="javascript:void(0);" class="btn_arrow last" @click="changePageLast">마지막으로</a>
</div>
</template>
<script>
export default {
name: 'Pagination',
props: {
total: {
type: [Number, String],
default: 0
},
pageSize: {
type: [Number, String],
default: 10
},
currentPage: {
type: [Number, String],
default: 1
},
className: {
type: String,
default: ''
},
rangeMax: {
type: [Number, String],
default: 10
}
},
data() {
return {
range: 0
}
},
created() {},
mounted() {},
computed: {
visiblePage() {
let range = []
for (let i = this.rangeStart; i <= this.rangeEnd; i++) {
range.push(i)
}
return range
},
lastPage() {
return parseInt(this.total) > 0
? Math.ceil(parseInt(this.total) / parseInt(this.pageSize))
: 1
},
rangeStart() {
return parseInt(this.rangeMax) * this.range + 1
},
rangeEnd() {
return parseInt(this.rangeMax) * (this.range + 1) < this.lastPage
? parseInt(this.rangeMax) * (this.range + 1)
: this.lastPage
},
lastRange() {
return parseInt(this.total) > 0
? Math.ceil(
parseInt(this.total) /
(parseInt(this.pageSize) * parseInt(this.rangeMax))
)
: 0
}
},
watch: {
total() {
this.init()
},
currentPage() {
this.setRange()
}
},
methods: {
init() {
this.range = 0
},
setRange() {
this.range = Math.floor(
(parseInt(this.currentPage) - 1) / parseInt(this.rangeMax)
)
},
changePage(page) {
this.$emit('update:currentPage', page)
this.$emit('change', page)
},
changeRangePrev() {
if (this.range > 0) {
this.range -= 1
this.$emit('update:currentPage', this.rangeStart)
this.$emit('change', this.rangeStart)
}
},
changeRangeNext() {
if (this.range < this.lastRange - 1) {
this.range += 1
this.$emit('update:currentPage', this.rangeStart)
this.$emit('change', this.rangeStart)
}
},
changePageFirst() {
this.range = 0
this.$emit('update:currentPage', 1)
this.$emit('change', 1)
},
changePageLast() {
if (parseInt(this.total) > 0) {
this.range = this.lastRange - 1
} else {
this.range = 0
}
this.$emit('update:currentPage', this.lastPage)
this.$emit('change', this.lastPage)
}
}
}
</script>
<style>
</style>

View File

@@ -1,61 +1,61 @@
<template>
<div class="tree-menu">
<div class="label-wrapper" v-if="depth > 0" @click="toggleChildren">
<div :style="indent" :class="labelClasses">
{{ label }}
<b v-if="nodes">[{{showChildren ? '-' : '+'}}]</b>
</div>
</div>
<span v-if="showChildren">
<TreeMenu
v-for="node in nodes"
:key="node.label"
:nodes="node.nodes"
:label="node.label"
:depth="depth + 1"
></TreeMenu>
</span>
</div>
</template>
<script>
export default {
name: "TreeMenu", // recursive component에는 name 설정 필수.
props: ["nodes", "label", "depth"],
data() {
return {
showChildren: true
};
},
computed: {
labelClasses() {
return { "has-children": this.nodes };
},
indent() {
return { transform: `translate(${(this.depth-1) * 50}px)` };
}
},
methods: {
toggleChildren() {
this.showChildren = !this.showChildren;
}
}
};
</script>
<style lang="scss" scoped>
.container {
width: 300px;
margin: 0 auto;
}
.tree-menu {
.label-wrapper {
padding-bottom: 10px;
margin-bottom: 10px;
.has-children {
cursor: pointer;
}
}
}
</style>
<template>
<div class="tree-menu">
<div class="label-wrapper" v-if="depth > 0" @click="toggleChildren">
<div :style="indent" :class="labelClasses">
{{ label }}
<b v-if="nodes">[{{showChildren ? '-' : '+'}}]</b>
</div>
</div>
<span v-if="showChildren">
<TreeMenu
v-for="node in nodes"
:key="node.label"
:nodes="node.nodes"
:label="node.label"
:depth="depth + 1"
></TreeMenu>
</span>
</div>
</template>
<script>
export default {
name: "TreeMenu", // recursive component에는 name 설정 필수.
props: ["nodes", "label", "depth"],
data() {
return {
showChildren: true
};
},
computed: {
labelClasses() {
return { "has-children": this.nodes };
},
indent() {
return { transform: `translate(${(this.depth-1) * 50}px)` };
}
},
methods: {
toggleChildren() {
this.showChildren = !this.showChildren;
}
}
};
</script>
<style lang="scss" scoped>
.container {
width: 300px;
margin: 0 auto;
}
.tree-menu {
.label-wrapper {
padding-bottom: 10px;
margin-bottom: 10px;
.has-children {
cursor: pointer;
}
}
}
</style>

View File

@@ -1,293 +1,293 @@
<template>
<grid
ref="tuiGrid"
:class="addClass"
:data="gridProps.data"
:columns="gridProps.columns"
:options="gridProps.options"
:language="gridProps.language"
@click="clicked"
@response="response"
@beforeRequest="beforeRequest"
:summary="gridProps.summary"
/>
<!--
- 공식홈: https://ui.toast.com/tui-grid
- vue git: https://github.com/nhn/toast-ui.vue-grid
- api & sample: https://nhn.github.io/tui.grid/latest/
- 연동 결과는 아래 포맷에 맞추어 주세요.
TuiGrid.java VO 참고
적용 : UserController > user
{
"result": true,
"data": {
"contents": [],
"pagination": {
"page": 1,
"totalCount": 100
}
}
}
-->
</template>
<script>
import 'tui-grid/dist/tui-grid.css';
import 'tui-pagination/dist/tui-pagination.css';
import TuiGrid from 'tui-grid';
import { Grid } from '@toast-ui/vue-grid';
export default {
name: 'tuiGrid',
props: [
'url', // 연동 url
'initialRequest', // false일 시 초기 렌더링 시 백엔드에 요청 하지 않음. 이 경우 readData를 호출하여 그리드 데이터를 할당해 줘야 함
'rowHeaders', // 체크 박스 등 헤더에 필요한 타입 ex) ["checkbox"]
'header', // 옵션 (헤더 병합 등)
'minRowHeight', // 리스트 row 높이
'minBodyHeight', // 테이블 높이
'pagination', // 페이지 네비게이션 사용 여부
'perPage', // 페이지 당 개수
'totalItems', // 부모창에 표시할 총 컨텐츠 개수 변수 명 (더 좋은 방법 있으면 알려주세요.)
'columns', // 컬럼 정보
'showVerticalBorder', // cell 세로라인 표시
'noDataStr', // 데이터가 없을 때
'noSearchStr', // 검색 결과가 없을 때
'scrollX', // 가로 스크롤 사용 여부
'scrollY', // 세로 스크롤 사용 여부
'addClass', // table에 추가할 클래스
'evtClick', // 클릭 이벤트 정보, 해당 커럼을 클릭하면 callback 수행, 이때 해당 row의 데이터를 파라미터로 반환한다. Object Or Array
// ex) evtClick: { column: "idx", callback: clickIdx }
// or evtClick: [ { column: "idx", callback: this.myFnc }, { column: "name", ... } ]
'summary'
],
components: {
grid: Grid
},
data() {
return {
instance: null,
gridProps: null,
currEventListener: null,
currGridEle: null,
currMode: 'normal'
};
},
mounted() {
this.saveGridEventListner();
//if(this.currMode != 'normal')
//this.initGridEventListner();
},
beforeDestroy() {
this.addGridEventListner();
},
created() {
/**
* Use the static method as below
*/
TuiGrid.applyTheme('default', {
outline: {
border: '#333 !important' // 테이블 위아래 선의 색깔 지정
},
row: {
hover: {
background: '#fafafa !important' // row 마우스 오버 시 색깔 지정
}
},
area: {
header: {
border: '#aaaaaa !important' // header 아래 선의 색깔 지정
}
},
cell: {
normal: {
showVerticalBorder: this.showVerticalBorder === true // 각 셀의 세로 선 노출
}
}
});
this.gridProps = {
data: {
api: {
readData: { url: this.url, method: 'GET' }
},
initialRequest: typeof this.initialRequest == 'undefined' ? true : this.initialRequest
},
options: {
rowHeaders: this.rowHeaders,
header: this.header ? this.header : { height: 47 },
minRowHeight: this.minRowHeight ? this.minRowHeight : 56,
minBodyHeight: this.minBodyHeight ? this.minBodyHeight : 56,
showDummyRows: true,
scrollX: this.scrollX === true,
scrollY: this.scrollY === true,
pagination: this.pagination,
pageOptions: {
perPage: this.perPage
}
},
language: {
name: 'ko',
value: {
display: {
noData: this.noDataStr
}
}
},
columns: this.columns,
summary: this.summary
};
},
methods: {
clicked: function(v) {
if (typeof this.evtClick != 'undefined' && this.evtClick != null) {
let data = this.$refs.tuiGrid.invoke('getRow', v.rowKey);
if (Array.isArray(this.evtClick)) {
for (var i = 0; i < this.evtClick.length; i++) {
if (v.columnName == this.evtClick[i].column && typeof this.evtClick[i].callback == 'function') {
this.evtClick[i].callback(data);
}
}
} else if (
this.evtClick.column != null &&
v.columnName == this.evtClick.column &&
typeof this.evtClick.callback == 'function'
) {
this.evtClick.callback(data);
}
}
},
response: function(event) {
let xhr = event.xhr;
let statusCode = xhr.status;
if (statusCode == 200) {
let respData = JSON.parse(xhr.response).data;
this.$parent[this.totalItems] = respData.pagination.totalCount;
let len = respData.contents.length;
if (this.scrollY == false) {
if (len > 0) {
let divLen = 6;
if (this.scrollX == true) {
divLen = 5;
}
// header의 height를 구할 수 있는 방법은? 일단 48
let addLen = len / divLen;
this.getGridInstance().setBodyHeight((len + addLen) * 48);
} else {
this.getGridInstance().setBodyHeight(48);
}
}
} else if (statusCode == 401 || statusCode == 418) {
alert('세션이 만료되었습니다.');
window.top.location.href = '/login';
} else {
window.top.location.href = '/view/error/' + statusCode;
}
},
beforeRequest: function(event) {
if (this.scrollY == false) {
this.getGridInstance().setBodyHeight(90);
}
},
getData: function() {
// 전체 Row 데이터를 가져온다.
return this.getGridInstance().getData();
},
getRow: function(rowKey) {
// 해당 Row의 데이터를 가져온다.
return this.getGridInstance().getRow(rowKey);
},
getPagination: function() {
// 페이지 정보
return this.getGridInstance().getPagination();
},
setPerPage: function(count) {
// 페이지 당 표시 개수 변경
this.getGridInstance().setPerPage(count);
},
readData: function(page, param) {
// 페이지 데이터 갱신 (initialRequest가 false일 경우 초기 데이터 로드시에도 사용)
this.getGridInstance().readData(page, param, true);
},
appendRow: function(rowData, rownum) {
var optionsOpt = {
at: rownum || 0,
extendPrevRowSpan: false,
focus: false
};
this.getGridInstance().appendRow(rowData, optionsOpt);
},
search: function(param) {
// 검색 결과가 없을 경우 텍스트 변경
let noSearchStr = '';
if (typeof this.noSearchStr == 'undefined') {
noSearchStr = '검색 결과가 없습니다.';
}
this.$refs.tuiGrid.language.value.display.noData = noSearchStr;
this.$refs.tuiGrid.setLanguage();
// param을 기반으로 리스트 갱신
this.readData(1, param);
},
gridMethod: function(params) {
return this.$refs.tuiGrid.invoke(...params);
},
getGridInstance() {
if (this.instance == null) {
this.instance = this.$refs.tuiGrid.gridInstance;
}
return this.instance;
},
saveGridEventListner() {
// this.currGridEle = document.querySelector(`div.tui-grid-container.tui-grid-show-lside-area`);
this.currGridEle = document.querySelector(`div.tui-grid-container`);
if (this.currGridEle != null && window.getEventListeners(this.currGridEle).mousedown) {
this.currEventListener = window.getEventListeners(this.currGridEle).mousedown[0].listener;
}
},
removeGridEventListner() {
this.currMode = 'edit';
this.currGridEle.removeEventListener('mousedown', this.currEventListener);
this.currGridEle.setAttribute('tabindex', '0');
this.currGridEle.style.outline = 'none';
this.currGridEle.addEventListener('keydown', this.copyEvent, false);
},
addGridEventListner() {
this.currMode = 'normal';
this.currGridEle.removeAttribute('tabindex');
this.currGridEle.removeEventListener('keydown', this.copyEvent);
this.currGridEle.addEventListener('mousedown', this.currEventListener);
},
initGridEventListner() {
document.querySelector(`div.tui-grid-container`).removeAttribute('tabindex');
document.querySelector(`div.tui-grid-container`).removeEventListener('keydown', this.copyEvent);
document.querySelector(`div.tui-grid-container`).addEventListener('mousedown', this.currEventListener);
},
copyEvent(ev) {
ev = ev || window.event;
var key = ev.which || ev.keyCode; // keyCode detection
var ctrl = ev.ctrlKey ? ev.ctrlKey : key === 17 ? true : false; // ctrl detection
if (key == 67 && ctrl) {
var clipboard = document.querySelector('.tui-grid-clipboard');
clipboard.innerHTML = this.getGridInstance().getFocusedCell().value;
clipboard.focus();
document.execCommand('copy');
}
}
}
};
</script>
<!-- 스타일 추가 CSS 우선순위를 높이기 위해 아래과 같이 .tui-grid-cell를 CSS 선택자에 포함시켜서 사용해야 적용 -->
<style>
.tui-grid-cell.cell-red {
background-color: red;
}
.tui-grid-table {
width: 100% !important;
}
</style>
<template>
<grid
ref="tuiGrid"
:class="addClass"
:data="gridProps.data"
:columns="gridProps.columns"
:options="gridProps.options"
:language="gridProps.language"
@click="clicked"
@response="response"
@beforeRequest="beforeRequest"
:summary="gridProps.summary"
/>
<!--
- 공식홈: https://ui.toast.com/tui-grid
- vue git: https://github.com/nhn/toast-ui.vue-grid
- api & sample: https://nhn.github.io/tui.grid/latest/
- 연동 결과는 아래 포맷에 맞추어 주세요.
TuiGrid.java VO 참고
적용 : UserController > user
{
"result": true,
"data": {
"contents": [],
"pagination": {
"page": 1,
"totalCount": 100
}
}
}
-->
</template>
<script>
import 'tui-grid/dist/tui-grid.css';
import 'tui-pagination/dist/tui-pagination.css';
import TuiGrid from 'tui-grid';
import { Grid } from '@toast-ui/vue-grid';
export default {
name: 'tuiGrid',
props: [
'url', // 연동 url
'initialRequest', // false일 시 초기 렌더링 시 백엔드에 요청 하지 않음. 이 경우 readData를 호출하여 그리드 데이터를 할당해 줘야 함
'rowHeaders', // 체크 박스 등 헤더에 필요한 타입 ex) ["checkbox"]
'header', // 옵션 (헤더 병합 등)
'minRowHeight', // 리스트 row 높이
'minBodyHeight', // 테이블 높이
'pagination', // 페이지 네비게이션 사용 여부
'perPage', // 페이지 당 개수
'totalItems', // 부모창에 표시할 총 컨텐츠 개수 변수 명 (더 좋은 방법 있으면 알려주세요.)
'columns', // 컬럼 정보
'showVerticalBorder', // cell 세로라인 표시
'noDataStr', // 데이터가 없을 때
'noSearchStr', // 검색 결과가 없을 때
'scrollX', // 가로 스크롤 사용 여부
'scrollY', // 세로 스크롤 사용 여부
'addClass', // table에 추가할 클래스
'evtClick', // 클릭 이벤트 정보, 해당 커럼을 클릭하면 callback 수행, 이때 해당 row의 데이터를 파라미터로 반환한다. Object Or Array
// ex) evtClick: { column: "idx", callback: clickIdx }
// or evtClick: [ { column: "idx", callback: this.myFnc }, { column: "name", ... } ]
'summary'
],
components: {
grid: Grid
},
data() {
return {
instance: null,
gridProps: null,
currEventListener: null,
currGridEle: null,
currMode: 'normal'
};
},
mounted() {
this.saveGridEventListner();
//if(this.currMode != 'normal')
//this.initGridEventListner();
},
beforeDestroy() {
this.addGridEventListner();
},
created() {
/**
* Use the static method as below
*/
TuiGrid.applyTheme('default', {
outline: {
border: '#333 !important' // 테이블 위아래 선의 색깔 지정
},
row: {
hover: {
background: '#fafafa !important' // row 마우스 오버 시 색깔 지정
}
},
area: {
header: {
border: '#aaaaaa !important' // header 아래 선의 색깔 지정
}
},
cell: {
normal: {
showVerticalBorder: this.showVerticalBorder === true // 각 셀의 세로 선 노출
}
}
});
this.gridProps = {
data: {
api: {
readData: { url: this.url, method: 'GET' }
},
initialRequest: typeof this.initialRequest == 'undefined' ? true : this.initialRequest
},
options: {
rowHeaders: this.rowHeaders,
header: this.header ? this.header : { height: 47 },
minRowHeight: this.minRowHeight ? this.minRowHeight : 56,
minBodyHeight: this.minBodyHeight ? this.minBodyHeight : 56,
showDummyRows: true,
scrollX: this.scrollX === true,
scrollY: this.scrollY === true,
pagination: this.pagination,
pageOptions: {
perPage: this.perPage
}
},
language: {
name: 'ko',
value: {
display: {
noData: this.noDataStr
}
}
},
columns: this.columns,
summary: this.summary
};
},
methods: {
clicked: function(v) {
if (typeof this.evtClick != 'undefined' && this.evtClick != null) {
let data = this.$refs.tuiGrid.invoke('getRow', v.rowKey);
if (Array.isArray(this.evtClick)) {
for (var i = 0; i < this.evtClick.length; i++) {
if (v.columnName == this.evtClick[i].column && typeof this.evtClick[i].callback == 'function') {
this.evtClick[i].callback(data);
}
}
} else if (
this.evtClick.column != null &&
v.columnName == this.evtClick.column &&
typeof this.evtClick.callback == 'function'
) {
this.evtClick.callback(data);
}
}
},
response: function(event) {
let xhr = event.xhr;
let statusCode = xhr.status;
if (statusCode == 200) {
let respData = JSON.parse(xhr.response).data;
this.$parent[this.totalItems] = respData.pagination.totalCount;
let len = respData.contents.length;
if (this.scrollY == false) {
if (len > 0) {
let divLen = 6;
if (this.scrollX == true) {
divLen = 5;
}
// header의 height를 구할 수 있는 방법은? 일단 48
let addLen = len / divLen;
this.getGridInstance().setBodyHeight((len + addLen) * 48);
} else {
this.getGridInstance().setBodyHeight(48);
}
}
} else if (statusCode == 401 || statusCode == 418) {
alert('세션이 만료되었습니다.');
window.top.location.href = '/login';
} else {
window.top.location.href = '/view/error/' + statusCode;
}
},
beforeRequest: function(event) {
if (this.scrollY == false) {
this.getGridInstance().setBodyHeight(90);
}
},
getData: function() {
// 전체 Row 데이터를 가져온다.
return this.getGridInstance().getData();
},
getRow: function(rowKey) {
// 해당 Row의 데이터를 가져온다.
return this.getGridInstance().getRow(rowKey);
},
getPagination: function() {
// 페이지 정보
return this.getGridInstance().getPagination();
},
setPerPage: function(count) {
// 페이지 당 표시 개수 변경
this.getGridInstance().setPerPage(count);
},
readData: function(page, param) {
// 페이지 데이터 갱신 (initialRequest가 false일 경우 초기 데이터 로드시에도 사용)
this.getGridInstance().readData(page, param, true);
},
appendRow: function(rowData, rownum) {
var optionsOpt = {
at: rownum || 0,
extendPrevRowSpan: false,
focus: false
};
this.getGridInstance().appendRow(rowData, optionsOpt);
},
search: function(param) {
// 검색 결과가 없을 경우 텍스트 변경
let noSearchStr = '';
if (typeof this.noSearchStr == 'undefined') {
noSearchStr = '검색 결과가 없습니다.';
}
this.$refs.tuiGrid.language.value.display.noData = noSearchStr;
this.$refs.tuiGrid.setLanguage();
// param을 기반으로 리스트 갱신
this.readData(1, param);
},
gridMethod: function(params) {
return this.$refs.tuiGrid.invoke(...params);
},
getGridInstance() {
if (this.instance == null) {
this.instance = this.$refs.tuiGrid.gridInstance;
}
return this.instance;
},
saveGridEventListner() {
// this.currGridEle = document.querySelector(`div.tui-grid-container.tui-grid-show-lside-area`);
this.currGridEle = document.querySelector(`div.tui-grid-container`);
if (this.currGridEle != null && window.getEventListeners(this.currGridEle).mousedown) {
this.currEventListener = window.getEventListeners(this.currGridEle).mousedown[0].listener;
}
},
removeGridEventListner() {
this.currMode = 'edit';
this.currGridEle.removeEventListener('mousedown', this.currEventListener);
this.currGridEle.setAttribute('tabindex', '0');
this.currGridEle.style.outline = 'none';
this.currGridEle.addEventListener('keydown', this.copyEvent, false);
},
addGridEventListner() {
this.currMode = 'normal';
this.currGridEle.removeAttribute('tabindex');
this.currGridEle.removeEventListener('keydown', this.copyEvent);
this.currGridEle.addEventListener('mousedown', this.currEventListener);
},
initGridEventListner() {
document.querySelector(`div.tui-grid-container`).removeAttribute('tabindex');
document.querySelector(`div.tui-grid-container`).removeEventListener('keydown', this.copyEvent);
document.querySelector(`div.tui-grid-container`).addEventListener('mousedown', this.currEventListener);
},
copyEvent(ev) {
ev = ev || window.event;
var key = ev.which || ev.keyCode; // keyCode detection
var ctrl = ev.ctrlKey ? ev.ctrlKey : key === 17 ? true : false; // ctrl detection
if (key == 67 && ctrl) {
var clipboard = document.querySelector('.tui-grid-clipboard');
clipboard.innerHTML = this.getGridInstance().getFocusedCell().value;
clipboard.focus();
document.execCommand('copy');
}
}
}
};
</script>
<!-- 스타일 추가 CSS 우선순위를 높이기 위해 아래과 같이 .tui-grid-cell를 CSS 선택자에 포함시켜서 사용해야 적용 -->
<style>
.tui-grid-cell.cell-red {
background-color: red;
}
.tui-grid-table {
width: 100% !important;
}
</style>

View File

@@ -1,27 +1,27 @@
<template>
<select v-model="perCnt" @change="perPage">
<option v-for="(cnt, index) in perList" :key="index" :value="cnt">{{cnt}}</option>
</select>
</template>
<script>
export default {
name: "tuiGridPerPage",
props: [
"grid", // tuiGrid의 ref 값
"per", // 초기 tuiGrid의 페이지 당 개수
"perList" // 페이지 당 개수 정보 ex: countList: [5, 10, 50, 100]
],
data() {
return {
perCnt: this.per
}
},
methods: {
perPage: function() {
this.$parent.$refs[this.grid].setPerPage(this.perCnt);
}
}
}
<template>
<select v-model="perCnt" @change="perPage">
<option v-for="(cnt, index) in perList" :key="index" :value="cnt">{{cnt}}</option>
</select>
</template>
<script>
export default {
name: "tuiGridPerPage",
props: [
"grid", // tuiGrid의 ref 값
"per", // 초기 tuiGrid의 페이지 당 개수
"perList" // 페이지 당 개수 정보 ex: countList: [5, 10, 50, 100]
],
data() {
return {
perCnt: this.per
}
},
methods: {
perPage: function() {
this.$parent.$refs[this.grid].setPerPage(this.perCnt);
}
}
}
</script>

View File

@@ -1,116 +1,116 @@
`
샘플 문서, 추후 삭제 예정 입니다.
`
<template>
<grid ref="tuiGrid"
:data="gridProps.data"
:columns="gridProps.columns"
:options="gridProps.options"
@click="clicked"
/>
</template>
<script>
import 'tui-grid/dist/tui-grid.css'
import { Grid } from '@toast-ui/vue-grid'
class inputTag {
constructor(props) {
const el = document.createElement('input');
el.type = "text";
el.style.width = "80%";
this.el = el;
this.render(props);
}
getElement() {
return this.el;
}
render(props) {
this.el.value = "test";
//this.el.value = String(props.value.chatbotId);
}
}
class divTag {
constructor(props) {
const div = document.createElement("div");
// props >> 컬럼 데이터. 하위 데이터가 있다면 props.value.xxx로 접근 가능하다.
div.appendChild(document.createElement("div")).textContent = "id: " + props.value.chatbotId
div.appendChild(document.createElement("div")).textContent = "snum: " + props.value.subNum
this.el = div;
}
getElement() {
return this.el;
}
}
export default {
components: {
'grid': Grid
},
data() {
return {
gridProps: null
}
},
created() {
this.gridProps = {
data: {
api: {
readData: { url: '/api/test/test', method: 'GET' },
}
},
pageOptions: {
perPage: 5
},
options: {
header: {
height: 100,
// 헤더 merge
complexColumns: [
{ header: "브랜드 모음", name: 'mergeColumn1', childNames: ["corpId", "mergeBrand", "mergeInfo"] },
{ header: "브랜드", name: 'mergeBrand', childNames: ["brId", "brNm"] },
{ header: "정보", name: 'mergeInfo', childNames: ["useYn", "apprYn", "apprReqYmd", "apprYmd"] }
]
}
},
// 헤더
columns: [
{ name: "corpId", header: "회사 아이디", align: "center" },
{ name: "brId", header: "브랜드 아이디", align: "center" },
{ name: "brNm", header: "브랜드 명", align: "center", sortable: true },
{ name: "useYn", header: "사용 여부", align: "center" },
{ name: "apprYn", header: "승인 여부", align: "center" },
{ name: "apprReqYmd", header: "승인요청 날짜", align: "center", sortable: true },
{ name: "apprYmd", header: "승인 날짜", align: "center", sortable: true },
{ name: "noname", header: "커스텀 1", align: "center", renderer: {
type: inputTag // 별도의 컬럼 구성이 필요한 경우
}},
{ name: "chatbot", header: "커스텀 2", align: "center", renderer: {
type: divTag // 별도의 컬럼 구성이 필요한 경우
}}
]
}
},
mounted() {
this.linkTo();
},
methods: {
linkTo: function() {
this.$refs.tuiGrid.invoke("addCellClassName", "0", "corpId", "cell-red");
},
clicked: function(v) {
var data = this.$refs.tuiGrid.invoke("getRow", v.rowKey);
alert("브랜드 아이디(" + data.brId + ") 클릭");
}
}
}
</script>
<style>
.tui-grid-cell.cell-red {background-color: red}
</style>
`
샘플 문서, 추후 삭제 예정 입니다.
`
<template>
<grid ref="tuiGrid"
:data="gridProps.data"
:columns="gridProps.columns"
:options="gridProps.options"
@click="clicked"
/>
</template>
<script>
import 'tui-grid/dist/tui-grid.css'
import { Grid } from '@toast-ui/vue-grid'
class inputTag {
constructor(props) {
const el = document.createElement('input');
el.type = "text";
el.style.width = "80%";
this.el = el;
this.render(props);
}
getElement() {
return this.el;
}
render(props) {
this.el.value = "test";
//this.el.value = String(props.value.chatbotId);
}
}
class divTag {
constructor(props) {
const div = document.createElement("div");
// props >> 컬럼 데이터. 하위 데이터가 있다면 props.value.xxx로 접근 가능하다.
div.appendChild(document.createElement("div")).textContent = "id: " + props.value.chatbotId
div.appendChild(document.createElement("div")).textContent = "snum: " + props.value.subNum
this.el = div;
}
getElement() {
return this.el;
}
}
export default {
components: {
'grid': Grid
},
data() {
return {
gridProps: null
}
},
created() {
this.gridProps = {
data: {
api: {
readData: { url: '/api/test/test', method: 'GET' },
}
},
pageOptions: {
perPage: 5
},
options: {
header: {
height: 100,
// 헤더 merge
complexColumns: [
{ header: "브랜드 모음", name: 'mergeColumn1', childNames: ["corpId", "mergeBrand", "mergeInfo"] },
{ header: "브랜드", name: 'mergeBrand', childNames: ["brId", "brNm"] },
{ header: "정보", name: 'mergeInfo', childNames: ["useYn", "apprYn", "apprReqYmd", "apprYmd"] }
]
}
},
// 헤더
columns: [
{ name: "corpId", header: "회사 아이디", align: "center" },
{ name: "brId", header: "브랜드 아이디", align: "center" },
{ name: "brNm", header: "브랜드 명", align: "center", sortable: true },
{ name: "useYn", header: "사용 여부", align: "center" },
{ name: "apprYn", header: "승인 여부", align: "center" },
{ name: "apprReqYmd", header: "승인요청 날짜", align: "center", sortable: true },
{ name: "apprYmd", header: "승인 날짜", align: "center", sortable: true },
{ name: "noname", header: "커스텀 1", align: "center", renderer: {
type: inputTag // 별도의 컬럼 구성이 필요한 경우
}},
{ name: "chatbot", header: "커스텀 2", align: "center", renderer: {
type: divTag // 별도의 컬럼 구성이 필요한 경우
}}
]
}
},
mounted() {
this.linkTo();
},
methods: {
linkTo: function() {
this.$refs.tuiGrid.invoke("addCellClassName", "0", "corpId", "cell-red");
},
clicked: function(v) {
var data = this.$refs.tuiGrid.invoke("getRow", v.rowKey);
alert("브랜드 아이디(" + data.brId + ") 클릭");
}
}
}
</script>
<style>
.tui-grid-cell.cell-red {background-color: red}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -1,19 +1,19 @@
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import { coreUiMixin } from "@/common/vue-mixins";
import jglib from '@/utils/jglib';
Vue.config.productionTip = false;
Vue.mixin(coreUiMixin);
Vue.prototype.runModeType = "LIVE";
new Vue({
router,
store,
jglib,
render: h => h(App)
}).$mount('#app')
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import { coreUiMixin } from "@/common/vue-mixins";
import jglib from '@/utils/jglib';
Vue.config.productionTip = false;
Vue.mixin(coreUiMixin);
Vue.prototype.runModeType = "LIVE";
new Vue({
router,
store,
jglib,
render: h => h(App)
}).$mount('#app')

View File

@@ -1,33 +1,33 @@
import CustList from '../views/CustList'
import MemberList from '../views/MemberList'
import SubsDetail from '../views/SubsDetail'
import MemberDetail from '../views/MemberDetail'
export default [
{
path: '/custMgt/subsList',
component: CustList,
name: 'subsList',
meta: { public: true }
},
{
path: '/custMgt/memberList',
component: MemberList,
name: 'memberList',
meta: { public: true }
},
{
path: '/custMgt/subsDetail',
component: SubsDetail,
name: 'subsDetail',
meta: { public: true }
},
{
path: '/custMgt/memberDetail',
component: MemberDetail,
name: 'memberDetail',
meta: { public: true }
},
]
import CustList from '../views/CustList'
import MemberList from '../views/MemberList'
import SubsDetail from '../views/SubsDetail'
import MemberDetail from '../views/MemberDetail'
export default [
{
path: '/custMgt/subsList',
component: CustList,
name: 'subsList',
meta: { public: true }
},
{
path: '/custMgt/memberList',
component: MemberList,
name: 'memberList',
meta: { public: true }
},
{
path: '/custMgt/subsDetail',
component: SubsDetail,
name: 'subsDetail',
meta: { public: true }
},
{
path: '/custMgt/memberDetail',
component: MemberDetail,
name: 'memberDetail',
meta: { public: true }
},
]

View File

@@ -1,211 +1,285 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">청약고객정보목록조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<!-- <form autocomplete="off" class="search_form"> -->
<div class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right" v-model="grid.params.searchType1">
<option value="">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right" v-model="grid.params.searchType2">
<option value="">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력" v-model="grid.params.searchText1"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력" v-model="grid.params.searchText2"/>
</div>
<button type="button" class="button grey" v-on:click="search">조회</button>
</div>
</div>
<!-- </form> -->
<div class="info">
<!-- <div class="count"> <span>100</span></div> -->
<div class="count"> <span>{{ totalItems }}</span></div>
<div class="button_group">
<button type="button" class="button blue admin" @click="ModalOpen('modal20')">관리자 등록</button>
<button type="button" class="button blue channel" @click="ModalOpen('modal23')">유지채널 등록</button>
<button type="button" class="button white delete" @click="deleteRow()">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="grid.url"
:perPage="grid.perPage"
:initialRequest="grid.initialRequest"
:pagination="grid.pagination"
:isCheckbox="grid.isCheckbox"
:columns="grid.columns"
:noDataStr="grid.noDataStr"
:addCls="grid.addCls"
:header="grid.headder"
></custom-grid>
</div>
<system-popup ref="systemModal"></system-popup>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
import SystemPopup from '@/components/SystemPopup.vue';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
totalItems: 0,
grid: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60},
{ name: 'auth', header: '권한', align: 'center', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
params: {
searchType1: '',
searchType2: '',
searchText1: '',
searchText2: ''
},
excelHeader: []
}
};
},
components: {
customGrid: customGrid,
SystemPopup
},
created(){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
//let cont = document.querySelector(".wrap");
//cont.classList.add("main_wrap");
},
destroyed() {
},
mounted() {
let page = 1;
// 페이지 정보 및 검색 조건
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
let isKeep = false;
if (getCondition) {
this.grid.perPage = getCondition.perPage;
this.grid.params = getCondition.params;
if (getCondition.sort != undefined && getCondition.sort != null) {
this.grid.params.sort = getCondition.sort;
}
page = getCondition.page;
isKeep = true;
}
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.grid.params);
this.$refs.table.search(this.grid.params, isKeep);
},
ModalOpen: function(target){
this.$refs.systemModal.ModalOpen(target);
},
deleteRow: function(){ //로우데이터 삭제하도록 수정
var checkTest = this.$refs.table.checkedElementDatas();
if(checkTest.length == 0){
alert('체크박스에 체크를 해주세요.')
}
for(var i = 0; i < checkTest.length; i++){
alert(checkTest[i].adminId);
}
},
memberDetail: function(data) {
if(data.adminId == 'free'){
this.$router.push({
path: `./views/MemberDetail`
});
}
},
}
};
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">청약고객관리</h3>
<p class="breadcrumb">고객관리 &gt; 청약고객관리 &gt; 회원관리</p>
</div>
<div class="top_tab">
<a href="customer_01_list.html" class="on">청약고객관리</a><a href="customer_02_list.html">회원관리</a>
</div>
<div class="search_form">
<div class="search_wrap">
<div class="group">
<div class="input_box cal">
<label for="right" class="label">조회기간</label>
<input class="" type="text" id="" v-model="grid.params.startDt"/>
<input class="" type="text" id="" v-model="grid.params.endDt"/>
</div>
<div class="select_box id">
<label for="right" class="label">상태</label>
<select name="" id="" v-model="grid.params.searchType1">
<option value="">전체</option>
<option value="사용">사용</option>
<option value="정지">정지</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">구분</label>
<select name="" id="" v-model="grid.params.searchType2">
<option value="">전체</option>
<option value="관리자">관리자</option>
<option value="사용자">사용자</option>
<option value="테스트">테스트</option>
</select>
</div>
</div>
<div class="group">
<div class="select_box">
<label for="right" class="label">상세검색</label>
<select name="" id="" v-model="grid.params.searchType3">
<option value="">전체</option>
<option value="ID">ID</option>
<option value="이름">이름</option>
<option value="관리자ID">관리자ID</option>
</select>
</div>
<div class="input_box">
<input class="search-box" type="text" id="search" placeholder="검색어 입력" v-model="grid.params.searchText1"/>
</div>
<button type="button" class="button grey" @click="search">조회</button>
</div>
</div>
</div>
<div class="info">
<div class="count"> <span>{{ totalItems }}</span>
<div class="select_box NumberSe">
<select name="" id="" v-model="perPageCnt" @change="changePerPage()">
<option v-for="option in options" v-bind:value="option.value" v-bind:key="option.value">{{ option.text }}</option>
</select>
</div>
</div>
<div class="button_group">
<button type="button" class="button blue">테스트 ID 생성</button>
</div>
</div>
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="grid.url"
:pagePerRows="grid.pagePerRows"
:initialRequest="grid.initialRequest"
:pagination="grid.pagination"
:isCheckbox="grid.isCheckbox"
:columns="grid.columns"
:noDataStr="grid.noDataStr"
:addCls="grid.addCls"
:header="grid.headder"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
import moment from 'moment';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
// 달력 데이터
sDateDiv: 'day',
eDateDiv: 'year',
startDate: null,
endDate: null,
disabledSDate: { from: new Date()},
disabledEDate: { to: new Date()},
// 테이블 리스트 데이터
perPageCnt: 20,
options: [
{ text: '20', value: 20},
{ text: '50', value: 50},
{ text: '100', value: 100}
],
totalItems: 0,
grid: {
url: '/api/v1/bo/custMgt/subsList',
pagePerRows: 20,
pagination: true,
isCheckbox: false, // true:첫번째 컬럼 앞에 체크박스 생성 / false:체크박스 제거
initialRequest: false,
addCls: 'box_OFvis',
/*
header: [
[
{ header: 'NO', childNames: [] },
{ header: '서비스 ID\n(관리자 ID)', childNames: [] },
{ header: '고객사명', childNames: [] },
{ header: '가입번호', childNames: [] },
{ header: '가입일', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '유치채널', childNames: [] },
{ header: '요금제', childNames: [] },
{ header: '이월누적금액', childNames: [] }
]
],
*/
columns: [
{ name: 'no', header: 'No', align: 'center', width: 60},
{ name: 'serviceId', header: '서비스 ID\n(관리자 ID)', align: 'center', width: 160 },
{ name: 'custNm', header: '고객사명', align: 'center', width: 130},
{ name: 'regNo', header: '가입번호', align: 'center', width: 130},
{ name: 'regDt', header: '가입일', align: 'center', width: 130, cls: 'td_line'},
{ name: 'stat', header: '상태', align: 'center', width: 130},
{ name: 'channel', header: '유치채널', align: 'center', width: 130},
{ name: 'plan', header: '요금제', align: 'center', width: 130},
{ name: 'carryOver', header: '이월누적금액', align: 'center', width: 130}
],
noDataStr: '검색 결과가 없습니다.',
params: {
searchType1: '',
searchType2: '',
searchType3: '',
searchText1: '',
startDt: '',
endDt: ''
},
excelHeader: []
}
};
},
components: {
customGrid: customGrid,
},
created(){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
//let cont = document.querySelector(".wrap");
//cont.classList.add("main_wrap");
},
destroyed() {
},
mounted() {
// 달력 세팅
this.grid.params.startDt = this.customFormatter(new Date());
this.grid.params.endDt = this.customFormatter(new Date());
let page = 1;
// 페이지 정보 및 검색 조건
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
console.log('getCondition : '+getCondition);
// store에 저장된 페이지 정보 및 검색 조건을 불러오기
let isKeep = false;
if (getCondition) {
this.grid.pagePerRows = getCondition.perPage;
this.grid.params = getCondition.params;
page = getCondition.page;
isKeep = true;
}
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log('this.perPageCnt'+this.perPageCnt);
//console.log(this.grid.params);
this.$refs.table.search(this.grid.params, isKeep);
this.sendStoreData();
},
ModalOpen: function(target){
this.$refs.systemModal.ModalOpen(target);
},
deleteRow: function(){ //로우데이터 삭제하도록 수정
var checkTest = this.$refs.table.checkedElementDatas();
if(checkTest.length == 0){
alert('체크박스에 체크를 해주세요.')
}
for(var i = 0; i < checkTest.length; i++){
alert(checkTest[i].adminId);
}
},
memberDetail: function(data) {
if(data.adminId == 'free'){
this.$router.push({
path: `./views/MemberDetail`
});
}
},
changePerPage: function(){ // 페이지당 조회할 개수
this.grid.pagePerRows = this.perPageCnt;
this.search(true);
},
sendStoreData: function() {
const getP = this.$refs.table.getPagination();
console.log("==========getP : " + getP._currentPage);
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params
});
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
console.log("getCondition : "+ getCondition.perPage);
},
customFormatter: function(date) {
// 달력 관련
if (this.sDateDiv == 'month') {
return moment(date).format('YYYY-MM');
} else if (this.sDateDiv == 'year') {
return moment(date).format('YYYY');
} else {
return moment(date).format('YYYY-MM-DD');
}
},
selectedStartDate(day) {
if (this.startDate > this.endDate) {
this.startDate = this.endDate;
}
},
selectedEndDate(day) {
if (day != undefined && day != null) {
this.periodDay = day;
}
},
closeDate(type) {
if (type != undefined && type != null) {
if (type == 'start') {
this.disabledSDate = { from: this.endDate };
this.disabledEDate = { to: this.startDate, from: this.endDate };
} else if (type == 'end') {
this.disabledSDate = { from: this.endDate };
this.disabledEDate = { to: this.startDate, from: new Date() };
}
}
},
},
beforeRouteLeave(to, from, next) {
const getP = this.$refs.table.getPagination();
console.log("==========getP : " + getP._currentPage);
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params
});
// 라우트 하기전 실행
next();
}
};
</script>

View File

@@ -1,165 +1,165 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">회원 정보 상세 조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력"/>
</div>
<button type="button" class="button grey">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>100</span></div>
<div class="button_group">
<button type="button" class="button blue admin">관리자 등록</button>
<button type="button" class="button blue channel">유지채널 등록</button>
<button type="button" class="button white delete">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="testList.url"
:perPage="testList.perPage"
:initialRequest="testList.initialRequest"
:pagination="testList.pagination"
:isCheckbox="testList.isCheckbox"
:columns="testList.columns"
:noDataStr="testList.noDataStr"
:addCls="testList.addCls"
:header="testList.header"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
testList: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60 },
{ name: 'auth', header: '권한', align: 'left', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
// params: {
// apprResult: '',
// searchType: '',
// searchText: '',
// startDate: '',
// endDate: ''
// },
excelHeader: []
}
};
},
components: {
customGrid: customGrid
},
destroyed() {
},
mounted() {
let isKeep = false;
isKeep = true;
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.testList.params);
this.$refs.table.search(this.testList.params, isKeep);
},
}
};
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">회원 정보 상세 조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력"/>
</div>
<button type="button" class="button grey">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>100</span></div>
<div class="button_group">
<button type="button" class="button blue admin">관리자 등록</button>
<button type="button" class="button blue channel">유지채널 등록</button>
<button type="button" class="button white delete">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="testList.url"
:perPage="testList.perPage"
:initialRequest="testList.initialRequest"
:pagination="testList.pagination"
:isCheckbox="testList.isCheckbox"
:columns="testList.columns"
:noDataStr="testList.noDataStr"
:addCls="testList.addCls"
:header="testList.header"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
testList: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60 },
{ name: 'auth', header: '권한', align: 'left', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
// params: {
// apprResult: '',
// searchType: '',
// searchText: '',
// startDate: '',
// endDate: ''
// },
excelHeader: []
}
};
},
components: {
customGrid: customGrid
},
destroyed() {
},
mounted() {
let isKeep = false;
isKeep = true;
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.testList.params);
this.$refs.table.search(this.testList.params, isKeep);
},
}
};
</script>

View File

@@ -1,165 +1,165 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">회원목록조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력"/>
</div>
<button type="button" class="button grey">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>100</span></div>
<div class="button_group">
<button type="button" class="button blue admin">관리자 등록</button>
<button type="button" class="button blue channel">유지채널 등록</button>
<button type="button" class="button white delete">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="testList.url"
:perPage="testList.perPage"
:initialRequest="testList.initialRequest"
:pagination="testList.pagination"
:isCheckbox="testList.isCheckbox"
:columns="testList.columns"
:noDataStr="testList.noDataStr"
:addCls="testList.addCls"
:header="testList.header"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
testList: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60 },
{ name: 'auth', header: '권한', align: 'left', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
// params: {
// apprResult: '',
// searchType: '',
// searchText: '',
// startDate: '',
// endDate: ''
// },
excelHeader: []
}
};
},
components: {
customGrid: customGrid
},
destroyed() {
},
mounted() {
let isKeep = false;
isKeep = true;
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.testList.params);
this.$refs.table.search(this.testList.params, isKeep);
},
}
};
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">회원목록조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력"/>
</div>
<button type="button" class="button grey">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>100</span></div>
<div class="button_group">
<button type="button" class="button blue admin">관리자 등록</button>
<button type="button" class="button blue channel">유지채널 등록</button>
<button type="button" class="button white delete">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="testList.url"
:perPage="testList.perPage"
:initialRequest="testList.initialRequest"
:pagination="testList.pagination"
:isCheckbox="testList.isCheckbox"
:columns="testList.columns"
:noDataStr="testList.noDataStr"
:addCls="testList.addCls"
:header="testList.header"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
testList: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60 },
{ name: 'auth', header: '권한', align: 'left', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
// params: {
// apprResult: '',
// searchType: '',
// searchText: '',
// startDate: '',
// endDate: ''
// },
excelHeader: []
}
};
},
components: {
customGrid: customGrid
},
destroyed() {
},
mounted() {
let isKeep = false;
isKeep = true;
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.testList.params);
this.$refs.table.search(this.testList.params, isKeep);
},
}
};
</script>

View File

@@ -1,165 +1,165 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">청약 정보 상세 조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력"/>
</div>
<button type="button" class="button grey">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>100</span></div>
<div class="button_group">
<button type="button" class="button blue admin">관리자 등록</button>
<button type="button" class="button blue channel">유지채널 등록</button>
<button type="button" class="button white delete">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="testList.url"
:perPage="testList.perPage"
:initialRequest="testList.initialRequest"
:pagination="testList.pagination"
:isCheckbox="testList.isCheckbox"
:columns="testList.columns"
:noDataStr="testList.noDataStr"
:addCls="testList.addCls"
:header="testList.header"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
testList: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60 },
{ name: 'auth', header: '권한', align: 'left', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
// params: {
// apprResult: '',
// searchType: '',
// searchText: '',
// startDate: '',
// endDate: ''
// },
excelHeader: []
}
};
},
components: {
customGrid: customGrid
},
destroyed() {
},
mounted() {
let isKeep = false;
isKeep = true;
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.testList.params);
this.$refs.table.search(this.testList.params, isKeep);
},
}
};
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">청약 정보 상세 조회</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="대리점">대리점</option>
<option value="운영자">운영자</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="right">
<option value="전체">전체</option>
<option value="사용">사용</option>
<option value="중지">중지</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력"/>
</div>
<button type="button" class="button grey">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>100</span></div>
<div class="button_group">
<button type="button" class="button blue admin">관리자 등록</button>
<button type="button" class="button blue channel">유지채널 등록</button>
<button type="button" class="button white delete">삭제</button>
</div>
</div>
<!-- <div class="table">
<table>
<colgroup>
<col width="5%"/>
<col width="15%"/>
<col width="15%"/>
<col width="20%"/>
<col width="20%"/>
<col width="5%"/>
<col width="20%"/>
</colgroup>
<thead>
<tr>
<th><input type="checkbox" id="admin_check1"><label for="admin_check1"></label></th>
<th>NO</th>
<th>권한</th>
<th>이름(대리점명)</th>
<th>ID</th>
<th>상태</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked id="admin_check2"><label for="admin_check2"></label></td>
<td>10</td>
<td>대리점</td>
<td>유플러스</td>
<td><a href="javascript:void(0)">uplus1</a></td>
<td>사용</td>
<td>2022-03-10</td>
</tr>
</tbody>
</table>
</div> -->
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="testList.url"
:perPage="testList.perPage"
:initialRequest="testList.initialRequest"
:pagination="testList.pagination"
:isCheckbox="testList.isCheckbox"
:columns="testList.columns"
:noDataStr="testList.noDataStr"
:addCls="testList.addCls"
:header="testList.header"
></custom-grid>
</div>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
//import api from '../service/api';
export default {
name: 'custList',
data() {
return {
testList: {
url: '/api/v1/bo/sysMgt/adminList',
perPage: 20,
pagination: true,
isCheckbox: true,
initialRequest: false,
addCls: 'box_OFvis',
header: [
[
{ header: 'NO', childNames: [] },
{ header: '권한', childNames: [] },
{ header: '이름(대리점명)', childNames: [] },
{ header: 'ID', childNames: [] },
{ header: '상태', childNames: [] },
{ header: '등록일', childNames: [] }
]
],
columns: [
{ name: 'no', header: 'NO', align: 'center', width: 60 },
{ name: 'auth', header: '권한', align: 'left', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130},
{ name: 'regDt', header: '등록일', width: 90, cls: 'td_line' }
],
noDataStr: '검색 결과가 없습니다.',
// params: {
// apprResult: '',
// searchType: '',
// searchText: '',
// startDate: '',
// endDate: ''
// },
excelHeader: []
}
};
},
components: {
customGrid: customGrid
},
destroyed() {
},
mounted() {
let isKeep = false;
isKeep = true;
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log(this.testList.params);
this.$refs.table.search(this.testList.params, isKeep);
},
}
};
</script>

View File

@@ -1,24 +1,31 @@
import LoginMain from '../views/LoginMain'
import LoginAuth from '../views/LoginAuth'
import ResetPassword from '../views/ResetPassword'
export default [
{
path: '/login',
name: 'login',
component: LoginMain,
meta: { public: true }
},
{
path: '/view/login/auth',
name: 'loginAuth',
component: LoginAuth,
meta: { public: true }
},
{
path: '/view/login/resetPassword',
name: 'resetPassword',
component: ResetPassword,
meta: { public: true }
},
import LoginMain from '../views/LoginMain'
import LoginAuth from '../views/LoginAuth'
import ResetPassword from '../views/ResetPassword'
import UpdatePassword from '../views/UpdatePassword'
export default [
{
path: '/login',
name: 'login',
component: LoginMain,
meta: { public: true }
},
{
path: '/view/login/auth',
name: 'loginAuth',
component: LoginAuth,
meta: { public: true }
},
{
path: '/view/login/resetPassword',
name: 'resetPassword',
component: ResetPassword,
meta: { public: true }
},
{
path: '/view/login/updatePassword',
name: 'updatePassword',
component: UpdatePassword,
meta: { public: true }
},
]

View File

@@ -1,53 +1,63 @@
import httpClient from '@/common/http-client';
const login = (params) => {
return httpClient.post('api/v1/bo/login/login', params, { headers: {"show-layer": "Yes"} },{ withCredentials: false });
};
const chgpwd = (params) => {
return httpClient.post('/api/oper/user/chgpwd', params);
};
const myphone = () => {
return httpClient.get('/api/oper/user/phone/self');
};
const phone = (params) => {
return httpClient.get('/api/public/auth/phone', { params: params });
};
// 삭제 예정
const reqnum = (params) => {
return httpClient.get('/api/public/auth/reqnum', { params: params });
};
const authNum = (params) => {
return httpClient.post('/api/v1/bo/login/authNum', params);
};
const confirmNum = (params) => {
//return httpClient.get('/api/public/auth/chknum', { params: params });
return httpClient.post('/api/v1/bo/login/confirmNum', params);
};
const newpwd = (params) => {
return httpClient.post('/api/public/auth/newpwd', params);
};
const logout = () => {
//return httpClient.get('/api/auth/logout', {headers: {"show-layer": "Yes"}});
return httpClient.post('/api/v1/bo/login/logout', {headers: {"show-layer": "Yes"}});
};
export default {
login,
logout,
chgpwd,
myphone,
phone,
reqnum,
confirmNum,
newpwd,
authNum
import httpClient from '@/common/http-client';
const login = (params) => {
return httpClient.post('api/v1/bo/login/login', params, { headers: {"show-layer": "Yes"} },{ withCredentials: false });
};
const chgpwd = (params) => {
return httpClient.post('/api/oper/user/chgpwd', params);
};
const myphone = () => {
return httpClient.get('/api/oper/user/phone/self');
};
const phone = (params) => {
return httpClient.get('/api/public/auth/phone', { params: params });
};
// 삭제 예정
const reqnum = (params) => {
return httpClient.get('/api/public/auth/reqnum', { params: params });
};
const authNum = (params) => {
return httpClient.post('/api/v1/bo/login/authNum', params);
};
const confirmNum = (params) => {
//return httpClient.get('/api/public/auth/chknum', { params: params });
return httpClient.post('/api/v1/bo/login/confirmNum', params);
};
const resetPassword = (params) => {
return httpClient.post('/api/v1/bo/login/resetPassword', params);
};
const updatePassword = (params) => {
return httpClient.post('/api/v1/bo/login/updatePassword', params);
};
const newpwd = (params) => {
return httpClient.post('/api/public/auth/newpwd', params);
};
const logout = () => {
//return httpClient.get('/api/auth/logout', {headers: {"show-layer": "Yes"}});
return httpClient.post('/api/v1/bo/login/logout', {headers: {"show-layer": "Yes"}});
};
export default {
login,
logout,
chgpwd,
myphone,
phone,
reqnum,
confirmNum,
newpwd,
authNum,
resetPassword,
updatePassword
};

View File

@@ -1,257 +1,258 @@
var commonPwdView = {
data: function() {
return {
err_msg: null,
message: {
curPwd: '', newPwd: '', cfmPwd: ''
},
param: {
userId: null, phone: null
},
curPwd: '', newPwd: '', cfmPwd: ''
};
},
methods: {
verifyNewPwd: function (evt) {
var valid = this.checkPassword(evt.target.value);
if (valid) {
this.err_msg = '';
}
this.message.newPwd = this.err_msg;
},
verifyCfmPwd: function() {
this.message.cfmPwd = '';
if (this.newPwd != this.cfmPwd) {
this.message.cfmPwd = this.cfmPwdFailMsg();
return false;
}
return true;
}
}
};
var validation = {
methods: {
checkId: function (id) {
if (id == null || id.trim() == "") {
this.err_msg = "아이디를 입력해 주세요.";
return false;
}
if (id.length < 4 || id.length > 15) {
this.err_msg = "아이디는 영문, 숫자를 이용하여 4자리 이상 15자리 이하이어야 합니다.";
return false;
}
if (!id.match(/^[0-9a-zA-Z]+$/)) {
this.err_msg = "아이디는 영문, 숫자를 이용하여야 합니다.";
return false;
}
return true;
},
checkPassword: function (pw) {
if (pw == null || pw.trim() == "") {
this.err_msg = "비밀번호를 입력해 주세요.";
return false;
}
if (typeof this.param.userId != "undefined") {
if (pw.indexOf(this.param.userId) >= 0) {
this.err_msg = "아이디가 포함된 문자열은 사용할 수 없습니다.";
return false;
}
}
for (var i = 0; i < pw.length; i++) {
var ch1 = pw.charAt(i);
var ch2 = pw.charAt(i + 1);
var ch3 = pw.charAt(i + 2);
var ch4 = pw.charAt(i + 3);
if (ch1 == ch2 && ch2 == ch3 && ch3 == ch4) {
//console.log(ch1 + "" + ch2 + "" + ch3 + ch4 + " is equality");
this.err_msg = "연속적인 숫자 또는 문자열은 사용할 수 없습니다.";
return false;
}
if (ch1.charCodeAt(0) - ch2.charCodeAt(0) == 1 && ch2.charCodeAt(0) - ch3.charCodeAt(0) == 1 && ch3.charCodeAt(0) - ch4.charCodeAt(0) == 1) {
//console.log(ch1 + "" + ch2 + "" + ch3 + ch4 + " is continuity");
this.err_msg = "연속적인 숫자 또는 문자열은 사용할 수 없습니다.";
return false;
}
if (ch1.charCodeAt(0) - ch2.charCodeAt(0) == -1 && ch2.charCodeAt(0) - ch3.charCodeAt(0) == -1 && ch3.charCodeAt(0) - ch4.charCodeAt(0) == -1) {
//console.log(ch1 + "" + ch2 + "" + ch3 + ch4 + " is continuity");
this.err_msg = "연속적인 숫자 또는 문자열은 사용할 수 없습니다.";
return false;
}
}
if (typeof this.param.phone != "undefined" && this.param.phone != null) {
var phone = this.param.phone;
phone = phone.substring(3, phone.length); // 앞 3자리 제거
var last = phone.substring(phone.length - 4, phone.length); // 뒤 4자리 추출
var middle = phone.substring(0, phone.length - 4); // 뒤 4자리 제거 == 국번
if (pw.indexOf(middle) >= 0 || pw.indexOf(last) >= 0) {
this.err_msg = "휴대폰번호가 포함된 문자열은 사용할 수 없습니다.";
return false
}
}
if (pw.length >= 10) {
if (pw.match(/^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])([a-zA-Z0-9!@#$%^&*]+)$/)) {
return true;
} else if (!pw.match(/^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$/)
&& !pw.match(/^(?=.*[0-9])(?=.*[!@#$%^&*])([0-9!@#$%^&*]+)$/)
&& !pw.match(/^(?=.*[a-zA-Z])(?=.*[!@#$%^&*])([a-zA-Z!@#$%^&*]+)$/)) {
this.err_msg = "영문, 숫자, 특수문자 중 2가지 이상 조합하여 10자리 이상 또는 3가지 이상 조합하여 8자리 이상이어야 합니다.";
return false;
}
} else if (pw.length >= 8) {
if (!pw.match(/^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])([a-zA-Z0-9!@#$%^&*]+)$/)) {
this.err_msg = "영문, 숫자, 특수문자 중 2가지 이상 조합하여 10자리 이상 또는 3가지 이상 조합하여 8자리 이상이어야 합니다.";
return false;
}
} else {
this.err_msg = "영문, 숫자, 특수문자 중 2가지 이상 조합하여 10자리 이상 또는 3가지 이상 조합하여 8자리 이상이어야 합니다.";
return false;
}
return true;
},
checkName: function (name) {
if (name == null || name.trim() == "") {
this.err_msg = "이름을 입력해 주세요.";
return false;
}
return true;
},
checkDeptNm: function (dept) {
if (dept == null || dept.trim() == "") {
this.err_msg = "부서명을 입력해 주세요.";
return false;
}
return true;
},
checkPhone: function (phone) {
if (phone == null || phone.trim() == "") {
this.err_msg = "휴대폰번호를 입력해 주세요.";
return false;
}
if (phone.length < 10) {
this.err_msg = "휴대폰번호를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkEmail: function (email) {
if (email == null || email.trim() == "") {
this.err_msg = "이메일을 입력해 주세요.";
return false;
}
// eslint-disable-next-line
if (!email.match(/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) {
this.err_msg = "이메일을 정확히 입력해 주세요.";
return false;
}
return true;
},
checkIp: function (param) {
if ((param.ip1 == null || param.ip1 == "") && (param.ip2 == null || param.ip2 == "") && (param.ip3 == null || param.ip3 == "") && (param.ip4 == null || param.ip4 == "")) {
this.err_msg = "접근허용 IP를 입력해 주세요.";
return false;
}
if ((param.ip1 == null || param.ip1 == "")
|| (param.ip2 == null || param.ip2 == "")
|| (param.ip3 == null || param.ip3 == "")
|| (param.ip4 == null || param.ip4 == "")) {
this.err_msg = "IP 주소를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkIpEach: function (ip, msg) {
if (ip == null || ip == "") {
this.err_msg = typeof msg != "undefined" ? msg : "접근허용 IP를 입력해 주세요.";
return false;
}
if (!ip.match(/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/)) {
this.err_msg = "IP 주소를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkIpWithAsterisk: function (ip, msg) {
if (ip == null || ip == "") {
this.err_msg = typeof msg != "undefined" ? msg : "접근허용 IP를 입력해 주세요.";
return false;
}
// 3레벨 이후 * 허용... 2레벨 이후 시 {2,3} 1레벨 이후시 {1,3} 필요 시 구문 추가
if (!ip.match(/^((((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}\*))$/)) {
this.err_msg = "IP 주소를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkRole: function (role) {
if (role == null || role == "") {
this.err_msg = "권한을 선택해 주세요.";
return false;
}
return true;
},
//리스크관리
checkSpamCliId: function (comnId, spamCliId) {
if (comnId == "N") {
if (spamCliId == null || spamCliId.trim() == "") {
this.err_msg = "SMID를 입력해 주세요.";
return false;
}
}
return true;
},
checkReqType: function (reqType) {
if (reqType == null || reqType.trim() == "") {
this.err_msg = "요청자를 선택해 주세요.";
return false;
}
return true;
},
checkSpamType: function (spamType) {
if (spamType == null || spamType.trim() == "") {
this.err_msg = "차단사유를 선택해 주세요.";
return false;
}
return true;
},
checkSpamContents: function (blockType) {
var str = "";
for (var k in this.callBacks) {
str = this.callBacks[k].spamContent;
if (blockType == "CLB") {
if (str == null || str.trim() == "") {
this.err_msg = "발신번호를 입력해 주세요.";
return false;
} else {
if (this.bytes(str) < 8) {
this.err_msg = "발신번호가 8자리 미만입니다.";
return false;
}
if (this.bytes(str) > 11) {
this.err_msg = "발신번호가 11자리 초과입니다.";
return false;
}
}
} else {
if (str == null || str.trim() == "") {
this.err_msg = "차단메시지를 입력해 주세요.";
return false;
}
}
}
return true;
}
}
};
var commonPwdView = {
data: function() {
return {
err_msg: null,
message: {
oldPw: '', newPw: '',
},
param: {
userId: null,
},
oldPw: '', newPw: '',
};
},
methods: {
verifyNewPw: function (evt) {
var valid = this.checkPassword(evt.target.value);
if (valid) {
this.err_msg = '';
}
this.message.newPw = this.err_msg;
},
verifyCfmPwd: function() {
this.message.cfmPw = '';
if (this.newPw != this.cfmPw) {
this.message.cfmPw = this.cfmPwdFailMsg();
return false;
}
return true;
}
}
};
var validation = {
methods: {
checkId: function (id) {
if (id == null || id.trim() == "") {
this.err_msg = "아이디를 입력해 주세요.";
return false;
}
if (id.length < 8 || id.length > 16) {
this.err_msg = "아이디는 영문, 숫자를 이용하여 4자리 이상 15자리 이하이어야 합니다.";
return false;
}
if (!id.match(/^[0-9a-zA-Z]+$/)) {
this.err_msg = "아이디는 영문, 숫자를 이용하여야 합니다.";
return false;
}
return true;
},
checkPassword: function (pw) {
if (pw == null || pw.trim() == "") {
this.err_msg = "비밀번호를 입력해 주세요.";
return false;
}
if (typeof this.param.userId != "undefined") {
if (pw.indexOf(this.param.userId) >= 0) {
this.err_msg = "아이디가 포함된 문자열은 사용할 수 없습니다.";
return false;
}
}
for (var i = 0; i < pw.length; i++) {
var ch1 = pw.charAt(i);
var ch2 = pw.charAt(i + 1);
var ch3 = pw.charAt(i + 2);
var ch4 = pw.charAt(i + 3);
if (ch1 == ch2 && ch2 == ch3 && ch3 == ch4) {
//console.log(ch1 + "" + ch2 + "" + ch3 + ch4 + " is equality");
this.err_msg = "연속적인 숫자 또는 문자열은 사용할 수 없습니다.";
return false;
}
if (ch1.charCodeAt(0) - ch2.charCodeAt(0) == 1 && ch2.charCodeAt(0) - ch3.charCodeAt(0) == 1 && ch3.charCodeAt(0) - ch4.charCodeAt(0) == 1) {
//console.log(ch1 + "" + ch2 + "" + ch3 + ch4 + " is continuity");
this.err_msg = "연속적인 숫자 또는 문자열은 사용할 수 없습니다.";
return false;
}
if (ch1.charCodeAt(0) - ch2.charCodeAt(0) == -1 && ch2.charCodeAt(0) - ch3.charCodeAt(0) == -1 && ch3.charCodeAt(0) - ch4.charCodeAt(0) == -1) {
//console.log(ch1 + "" + ch2 + "" + ch3 + ch4 + " is continuity");
this.err_msg = "연속적인 숫자 또는 문자열은 사용할 수 없습니다.";
return false;
}
}
if (typeof this.param.phone != "undefined" && this.param.phone != null) {
var phone = this.param.phone;
phone = phone.substring(3, phone.length); // 앞 3자리 제거
var last = phone.substring(phone.length - 4, phone.length); // 뒤 4자리 추출
var middle = phone.substring(0, phone.length - 4); // 뒤 4자리 제거 == 국번
if (pw.indexOf(middle) >= 0 || pw.indexOf(last) >= 0) {
this.err_msg = "휴대폰번호가 포함된 문자열은 사용할 수 없습니다.";
return false
}
}
if (pw.length >= 10) {
if (pw.match(/^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])([a-zA-Z0-9!@#$%^&*]+)$/)) {
return true;
} else if (!pw.match(/^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$/)
&& !pw.match(/^(?=.*[0-9])(?=.*[!@#$%^&*])([0-9!@#$%^&*]+)$/)
&& !pw.match(/^(?=.*[a-zA-Z])(?=.*[!@#$%^&*])([a-zA-Z!@#$%^&*]+)$/)) {
this.err_msg = "영문, 숫자, 특수문자 중 2가지 이상 조합하여 10자리 이상 또는 3가지 이상 조합하여 8자리 이상이어야 합니다.";
return false;
}
} else if (pw.length >= 8) {
if (!pw.match(/^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[!@#$%^&*])([a-zA-Z0-9!@#$%^&*]+)$/)) {
this.err_msg = "영문, 숫자, 특수문자 중 2가지 이상 조합하여 10자리 이상 또는 3가지 이상 조합하여 8자리 이상이어야 합니다.";
return false;
}
} else {
this.err_msg = "영문, 숫자, 특수문자 중 2가지 이상 조합하여 10자리 이상 또는 3가지 이상 조합하여 8자리 이상이어야 합니다.";
return false;
}
return true;
},
checkName: function (name) {
if (name == null || name.trim() == "") {
this.err_msg = "이름을 입력해 주세요.";
return false;
}
return true;
},
checkDeptNm: function (dept) {
if (dept == null || dept.trim() == "") {
this.err_msg = "부서명을 입력해 주세요.";
return false;
}
return true;
},
checkPhone: function (phone) {
if (phone == null || phone.trim() == "") {
this.err_msg = "휴대폰번호를 입력해 주세요.";
return false;
}
if (phone.length < 10) {
this.err_msg = "휴대폰번호를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkEmail: function (email) {
if (email == null || email.trim() == "") {
this.err_msg = "이메일을 입력해 주세요.";
return false;
}
// eslint-disable-next-line
if (!email.match(/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) {
this.err_msg = "이메일을 정확히 입력해 주세요.";
return false;
}
return true;
},
checkIp: function (param) {
if ((param.ip1 == null || param.ip1 == "") && (param.ip2 == null || param.ip2 == "") && (param.ip3 == null || param.ip3 == "") && (param.ip4 == null || param.ip4 == "")) {
this.err_msg = "접근허용 IP를 입력해 주세요.";
return false;
}
if ((param.ip1 == null || param.ip1 == "")
|| (param.ip2 == null || param.ip2 == "")
|| (param.ip3 == null || param.ip3 == "")
|| (param.ip4 == null || param.ip4 == "")) {
this.err_msg = "IP 주소를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkIpEach: function (ip, msg) {
if (ip == null || ip == "") {
this.err_msg = typeof msg != "undefined" ? msg : "접근허용 IP를 입력해 주세요.";
return false;
}
if (!ip.match(/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/)) {
this.err_msg = "IP 주소를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkIpWithAsterisk: function (ip, msg) {
if (ip == null || ip == "") {
this.err_msg = typeof msg != "undefined" ? msg : "접근허용 IP를 입력해 주세요.";
return false;
}
// 3레벨 이후 * 허용... 2레벨 이후 시 {2,3} 1레벨 이후시 {1,3} 필요 시 구문 추가
if (!ip.match(/^((((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}\*))$/)) {
this.err_msg = "IP 주소를 정확히 입력해 주세요.";
return false;
}
return true;
},
checkRole: function (role) {
if (role == null || role == "") {
this.err_msg = "권한을 선택해 주세요.";
return false;
}
return true;
},
//리스크관리
checkSpamCliId: function (comnId, spamCliId) {
if (comnId == "N") {
if (spamCliId == null || spamCliId.trim() == "") {
this.err_msg = "SMID를 입력해 주세요.";
return false;
}
}
return true;
},
checkReqType: function (reqType) {
if (reqType == null || reqType.trim() == "") {
this.err_msg = "요청자를 선택해 주세요.";
return false;
}
return true;
},
checkSpamType: function (spamType) {
if (spamType == null || spamType.trim() == "") {
this.err_msg = "차단사유를 선택해 주세요.";
return false;
}
return true;
},
checkSpamContents: function (blockType) {
var str = "";
for (var k in this.callBacks) {
str = this.callBacks[k].spamContent;
if (blockType == "CLB") {
if (str == null || str.trim() == "") {
this.err_msg = "발신번호를 입력해 주세요.";
return false;
} else {
if (this.bytes(str) < 8) {
this.err_msg = "발신번호가 8자리 미만입니다.";
return false;
}
if (this.bytes(str) > 11) {
this.err_msg = "발신번호가 11자리 초과입니다.";
return false;
}
}
} else {
if (str == null || str.trim() == "") {
this.err_msg = "차단메시지를 입력해 주세요.";
return false;
}
}
}
return true;
}
}
};
export { commonPwdView, validation };

View File

@@ -1,52 +1,52 @@
const state = {
token: null,
isLogin: false,
isErrorPage: false,
isAuthChk: false,
pwd: null
};
const getters = {
getToken: state => state.token,
isLogin: state => state.isLogin,
isErrorPage: state => state.isErrorPage,
isAuthChk: state => state.isAuthChk,
getPwd: state => state.pwd,
};
const mutations = {
saveToken: (state, token) => {
console.log('saveToken:', token);
state.token = token;
},
removeToken: (state) => {
console.log('removeToken:');
state.token = null;
},
isLogin: (state, value) => {
console.log("isLogin mutation : " + value);
state.isLogin = value;
},
isErrorPage: (state, value) => {
console.log("isErrorPage mutation : " + value);
state.isErrorPage = value;
},
isAuthChk: (state, value) => {
console.log("isAuthChk mutation : "+ value);
state.isAuthChk = value;
},
savePwd: (state, value) => {
state.pwd = value;
},
};
const actions = {
};
export default {
namespaced: true,
state,
getters,
mutations,
actions
};
const state = {
token: null,
isLogin: false,
isErrorPage: false,
isAuthChk: false,
pwd: null
};
const getters = {
getToken: state => state.token,
isLogin: state => state.isLogin,
isErrorPage: state => state.isErrorPage,
isAuthChk: state => state.isAuthChk,
getPwd: state => state.pwd,
};
const mutations = {
saveToken: (state, token) => {
console.log('saveToken:', token);
state.token = token;
},
removeToken: (state) => {
console.log('removeToken:');
state.token = null;
},
isLogin: (state, value) => {
console.log("isLogin mutation : " + value);
state.isLogin = value;
},
isErrorPage: (state, value) => {
console.log("isErrorPage mutation : " + value);
state.isErrorPage = value;
},
isAuthChk: (state, value) => {
console.log("isAuthChk mutation : "+ value);
state.isAuthChk = value;
},
savePwd: (state, value) => {
state.pwd = value;
},
};
const actions = {
};
export default {
namespaced: true,
state,
getters,
mutations,
actions
};

View File

@@ -1,263 +1,268 @@
<template>
<!-- s: 문자인증 -->
<div class="wrap bg-wrap">
<div class="login-box text-auth">
<div class="logo"></div>
<div class="wbox">
<h3 class="title">2 휴대폰 문자 인증</h3>
<p class="desc">아이디에 등록된 휴대폰번호를 입력해 주세요.</p>
<!-- <form action=""> -->
<ul class="pw-form">
<div>
<li><input type="text"
placeholder="휴대폰번호를 입력하세요 (숫자만 입력하세요.)"
v-model="mdn"
:maxlength="11"
oninput="javascript: this.value = this.value.replace(/[^0-9]/g, '');"
>
<button class="btn-p2color" v-on:click="authNum">인증번호 받기</button></li>
</div>
<div>
<li class="bg-g">
<input type="text"
placeholder="인증번호를 입력하세요"
v-model="confirmNum"
:maxlength="6"
oninput="javascript: this.value = this.value.replace(/[^0-9]/g, '');"
>
<span class="time"> {{ TimerStr }}</span></li>
</div>
<li>
<button class="btn-default" @click="clickMenu('/login')">취소</button>
<button class="btn-pcolor" v-on:click="ajaxAuth">확인</button>
</li>
</ul>
<!-- </form> -->
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import api from '../service/api';
import tokenSvc from '@/common/token-service';
import LoginPopup from '@/components/LoginPopup.vue'
//import * as utils from '@/common/utils';
export default {
data: function() {
return {
errors: [],
mdn: '',
confirmNum: '',
userId: '',
isAuthNum: false,
isLogin: true,
pwd: '',
text: '',
number: '',
Timer: null,
TimeCounter: 180,
TimerStr: "03:00"
};
},
components: {
LoginPopup : LoginPopup
},
created() {
if(!!tokenSvc.getToken()){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.$router.push({ path: '/' });
}else{
if(!this.getLogin){
this.$router.push({ path: '/login' });
}
}
},
mounted() {
if (localStorage.hubwebUserId) {
this.userId = localStorage.hubwebUserId;
}
this.isLogin = this.getLogin;
this.pwd = this.getPwd;
},
computed: {
...mapGetters({
getLogin: 'login/isLogin',
getErrorPage: 'login/isErrorPage',
getAuthChk: 'login/isAuthChk',
getPwd: 'login/getPwd'
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
getPwd(data) {
if(data != null && data != ''){
this.pwd = data;
}
}
},
destroyed() {
let cont = document.querySelector(".wrap");
cont.classList.remove("bg-wrap");
},
methods: {
// 2차 인증번호 요청
authNum(){
var vm = this;
if(!this.isLogin){
var vm = this;
vm.$store.commit("login/isLogin", false);
vm.$store.commit("login/isAuthChk", false);
vm.$router.push({ path: '/'});
return;
}
if (vm.mdn == null || vm.mdn.trim() == ""){
vm.ModalOpen('modal08');
return false;
} else if (vm.mdn.length < 11 || !vm.mdn) {
vm.ModalOpen('modal06');
}
var params = {
"oprtrId": this.userId,
"hpNo": this.mdn,
"isLogin" : this.isLogin
}
api.authNum(params).then(response => {
console.log(response);
var rsp = response.data;
if(rsp.retCode == '0000'){
this.Timer = this.timerStart();
vm.ModalOpen('modal07');
// console.log('시간 3:00 카운트 하기');
this.isAuthNum = true;
}else if (!this.Timer) {
this.timerStop(this.Timer);
this.Timer = null;
// 실패 -> 실패 코드에 따라 실패 팝업 보여주기
//인증시간 초과 후 “시간초과!” 문구로 변경
}
}).catch(response =>{
console.log(response);
});
},
// 2차 인증 확인
ajaxAuth: function(){
var vm = this;
if (!vm.formCheck()){
alert(vm.errors[0]);
return false;
}
if(vm.TimeCounter==0){
alert("시간초과");
return false;
}
var params = {
"oprtrId": this.userId,
"hpNo": this.mdn,
"chrVal": this.confirmNum,
"isLogin": this.isLogin,
"oprtrPw": this.pwd
}
//인증번호 확인
api.confirmNum(params).then(function(response){
var rsp = response.data;
console.log("RESULT_CODE : "+rsp.retCode);
if(rsp.retCode == '0000'){
vm.$store.commit("login/isLogin", true);
//var nextUrl = rsp.data.nextUrl;
//vm.$router.push({ path: nextUrl});
vm.$router.push({ path: '/'});
}else if(rsp.retCode == '4008') { //휴대폰번호 확인
vm.ModalOpen('modal06');
} else if(rsp.retCode == '404') { //인증번호: 입력
vm.ModalOpen('modal08');
} else if(rsp.retCode == '4009') { //인증실패: 시간초과
vm.ModalOpen('modal10');
} else if(rsp.retCode == '4010') { //인증실패: 인증번호
vm.ModalOpen('modal09');
} else if(rsp.retCode == '4011') { //인증실패: 5회
vm.ModalOpen('modal11');
} else{
return;
}
});
},
formCheck: function() {
this.errors = [];
if(!this.isAuthNum){
this.errors.push('인증요청을 먼저 해주세요.');
}
if(!this.mdn){
this.errors.push('휴대폰 번호를 확인해주세요.');
}
if(!this.confirmNum){
this.errors.push('인증번호를 입력하세요.');
}
return this.errors.length == 0;
},
clickMenu(link){
this.$router.push({
path: link
});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
},
timerStart: function() {
// 1초에 한번씩 start 호출
this.TimeCounter = 180;
var interval = setInterval(() => {
this.TimeCounter--;
//1초씩 감소
this.TimerStr = this.prettyTime();
if (this.TimeCounter <= 0)
{
this.timerStop(interval);
// this.ModalOpen('modal10');
}
}, 100);
return interval;
},
timerStop: function(Timer)
{
clearInterval(Timer);
this.TimeCounter = 0;
},
prettyTime: function() {
// 시간 형식으로 변환 리턴
let time = this.TimeCounter / 60;
let minutes = parseInt(time);
let secondes = Math.round((time - minutes) * 60);
return (
minutes.toString().padStart(2, "0") +
":"
+ secondes.toString().padStart(2, "0")
);
},
}
};
</script>
<template>
<!-- s: 문자인증 -->
<div class="wrap bg-wrap">
<div class="login-box text-auth">
<div class="logo"></div>
<div class="wbox">
<h3 class="title">2 휴대폰 문자 인증</h3>
<p class="desc">아이디에 등록된 휴대폰번호를 입력해 주세요.</p>
<!-- <form action=""> -->
<ul class="pw-form">
<div>
<li><input type="text"
placeholder="휴대폰번호를 입력하세요 (숫자만 입력하세요.)"
v-model="mdn"
:maxlength="11"
oninput="javascript: this.value = this.value.replace(/[^0-9]/g, '');"
@keyup.enter="authNum">
<button class="btn-p2color" v-on:click="authNum">인증번호 받기</button></li>
</div>
<div>
<li class="bg-g">
<input type="text"
placeholder="인증번호를 입력하세요"
v-model="confirmNum"
:maxlength="6"
oninput="javascript: this.value = this.value.replace(/[^0-9]/g, '');"
@keyup.enter="ajaxAuth">
<span class="time"> {{ timerStr }}</span></li>
</div>
<li>
<button class="btn-default" @click="clickMenu('/login')">취소</button>
<button class="btn-pcolor" v-on:click="ajaxAuth">확인</button>
</li>
</ul>
<!-- </form> -->
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import api from '../service/api';
import tokenSvc from '@/common/token-service';
import LoginPopup from '@/components/LoginPopup.vue'
//import * as utils from '@/common/utils';
export default {
data: function() {
return {
errors: [],
mdn: '01012341234',
confirmNum: '',
userId: '',
isAuthNum: false,
isLogin: true,
pwd: '',
text: '',
number: '',
timer: null,
timeCounter: 180,
timerStr: "03:00"
};
},
components: {
LoginPopup : LoginPopup
},
created() {
if(!!tokenSvc.getToken()){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.$router.push({ path: '/' });
}else{
if(!this.getLogin){
this.$router.push({ path: '/login' });
}
}
},
mounted() {
if (localStorage.hubwebUserId) {
this.userId = localStorage.hubwebUserId;
}
this.isLogin = this.getLogin;
this.pwd = this.getPwd;
},
computed: {
...mapGetters({
getLogin: 'login/isLogin',
getErrorPage: 'login/isErrorPage',
getAuthChk: 'login/isAuthChk',
getPwd: 'login/getPwd'
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
getPwd(data) {
if(data != null && data != ''){
this.pwd = data;
}
}
},
destroyed() {
let cont = document.querySelector(".wrap");
cont.classList.remove("bg-wrap");
},
methods: {
// 2차 인증번호 요청
authNum(){
var vm = this;
if(!this.isLogin){
vm.$store.commit("login/isLogin", false);
vm.$store.commit("login/isAuthChk", false);
vm.$router.push({ path: '/'});
return;
}
if (vm.mdn == null || vm.mdn.trim() == "" || vm.mdn.length < 11 || !vm.mdn){
vm.ModalOpen('modal06');
return false;
}
var params = {
"oprtrId": this.userId,
"hpNo": this.mdn,
"isLogin" : this.isLogin
}
api.authNum(params).then(response => {
console.log(response);
var rsp = response.data;
if(rsp.retCode == '0000'){
this.timerStop(this.timer);
this.timer = this.timerStart();
vm.ModalOpen('modal07');
// console.log('시간 3:00 카운트 하기');
this.isAuthNum = true;
}else if (!this.timer) {
this.timerStop(this.timer);
this.timer = null;
vm.ModalOpen('modal06');
// 실패 -> 실패 코드에 따라 실패 팝업 보여주기
//인증시간 초과 후 “시간초과!” 문구로 변경
}
}).catch(response =>{
console.log(response);
});
},
// 2차 인증 확인
ajaxAuth: function(){
var vm = this;
if (!vm.formCheck()){
alert(vm.errors[0]);
return false;
}
if(this.timeCounter == 0){
this.ModalOpen('modal10');
return false;
}
var params = {
"oprtrId": this.userId,
"hpNo": this.mdn,
"chrVal": this.confirmNum,
"isLogin": this.isLogin,
"oprtrPw": this.pwd
}
//인증번호 확인
api.confirmNum(params).then(function(response){
var rsp = response.data;
console.log("RESULT_CODE : "+rsp.retCode);
if(rsp.retCode == '0000'){
vm.$store.commit("login/isLogin", true);
//var nextUrl = rsp.data.nextUrl;
//vm.$router.push({ path: nextUrl});
vm.$router.push({ path: '/'});
}else if(rsp.retCode == '4008') { //휴대폰번호 확인
vm.ModalOpen('modal06');
}
// else if(rsp.retCode == '4009') { //인증실패: 시간초과
// vm.ModalOpen('modal10');
// }
else{
if(rsp.retCode == '4010') { //인증실패: 인증번호
vm.ModalOpen('modal09');
}
else if(rsp.retCode == '4011') { //인증실패: 5회
vm.ModalOpen('modal11');
// vm.$router.go(-1)
}
return;
}
// else{
// }
});
},
formCheck: function() {
this.errors = [];
if(!this.mdn){
this.ModalOpen('modal06');
} else if(!this.isAuthNum){
this.errors.push('인증요청을 먼저 해주세요.');
}else if(!this.confirmNum){
this.ModalOpen('modal08');
}
return this.errors.length == 0;
},
clickMenu(link){
this.$router.push({
path: link
});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
},
timerStart: function() {
// 1초에 한번씩 start 호출
this.timeCounter = 180;
var interval = setInterval(() => {
this.timeCounter--;
//1초씩 감소
this.timerStr = this.prettyTime();
if (this.timeCounter <= 0)
{
this.timerStop(interval);
}
}, 1000);
return interval;
},
timerStop: function(Timer)
{
clearInterval(Timer);
this.timeCounter = 0;
},
prettyTime: function() {
// 시간 형식으로 변환 리턴
let time = this.timeCounter / 60;
let minutes = parseInt(time);
let secondes = Math.round((time - minutes) * 60);
return (
minutes.toString().padStart(2, "0") +
":"
+ secondes.toString().padStart(2, "0")
);
},
}
};
</script>

View File

@@ -1,153 +1,154 @@
<template>
<div class="wrap bg-wrap">
<div class="login-box adm-login">
<div class="wbox">
<div class="logo"></div>
<h3 class="title">관리자 로그인</h3>
<!-- <form action=""> -->
<div class="login-form">
<li><input type="text" placeholder="아이디" v-model="userId"></li>
<li><input type="password" placeholder="비밀번호" v-model="userPwd"></li>
<li>
<span class="lcont"><input type="checkbox" id="id-remember" ref="chkSaveId" checked><label for="id-remember">아이디 저장</label></span>
<span class="rcont"><button class="btn-pwreset" @click="clickMenu('/view/login/resetPassword')">비밀번호 초기화</button></span>
</li>
<li><button class="btn-pcolor" v-on:click="ajaxlogin">로그인</button></li>
</div>
<!-- </form> -->
<div class="login-notice">
<div>
<li>비밀번호 분실 비밀번호 초기화를 이용해주세요.</li>
<li>비밀번호는 90일이내 변경하여 안전히 관리해주세요.</li>
</div>
</div>
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
import api from '../service/api';
import LoginPopup from '@/components/LoginPopup.vue';
import tokenSvc from '@/common/token-service';
//import * as utils from '@/common/utils';
export default {
data: function() {
return {
errors: [],
corpId: '',
userId: '',
userPwd: ''
};
},
created() {
// 로그인 페이지 진입시
if(!!tokenSvc.getToken()){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.$router.push({ path: '/' });
}else{
this.$store.commit("login/isLogin", false);
this.$store.commit("login/isAuthChk", false);
this.$store.commit("login/isErrorPage", false);
}
},
mounted() {
this.$refs.chkSaveId.checked = true;
if (localStorage.hubwebUserId) {
this.userId = localStorage.hubwebUserId;
}
},
destroyed() {
let cont = document.querySelector(".wrap");
cont.classList.remove("login-wrap");
},
components: {
LoginPopup : LoginPopup
},
methods: {
chgChkUserId() {
if (this.$refs.chkSaveId.checked == true) {
localStorage.hubwebUserId = this.userId;
} else {
delete localStorage.hubwebUserId;
}
},
toRegister(){
this.$router.push({ name: 'register'});
},
formCheck: function() {
this.errors = [];
if (!this.userId) this.errors.push('아이디를 입력해 주세요.');
if (!this.userPwd) this.errors.push('비밀번호를 입력해 주세요.');
return this.errors.length == 0;
},
ajaxlogin: function() {
var vm = this;
vm.errmsg = null;
if (!vm.formCheck()) return false;
let oprtrPw = this.userPwd;
// FormData 객체를 파라미터로 넘기면 Content-Type: multipart/form-data; 요청을 한다.
// 일반 Object를 파라미터로 넘기면 Content-Type: application/json;charset=UTF-8 요청을 한다.
var params = {
"oprtrId": this.userId,
"oprtrPw": this.userPwd,
}
//로그인버튼을 누를시 상황
api.login(params).then(function(response) {
var rsp = response.data;
if(rsp.retCode == '0000'){
var path = rsp.data.nextUrl;
console.log(path);
vm.chgChkUserId();
vm.$store.commit("login/isLogin", true);
vm.$store.commit("login/savePwd", oprtrPw);
vm.$router.push({ path: '/view/login/auth'});
} else if(rsp.retCode == '4004') { // ID/PWD 불일치
vm.errors.push('로그인 실패하였습니다. (5회 실패 시 계정 잠김)');
vm.ModalOpen('modal01');
} else if(rsp.retCode == '4005') { // ID/PWD 불일치 횟수초과로 계정 잠김
// msg = '5회 이상 로그인 실패하여 해당 아이디에 대한 계정이 잠금처리되었습니다.\n관리자에게 문의하세요.';
vm.ModalOpen('modal02');
} else if(rsp.retCode == '4006') {
// msg = '비밀번호를 변경하신지 90일이 지났습니다.\n비밀번호 변경 화면으로 이동합니다.';
vm.ModalOpen('modal04');
} else if(rsp.retCode == '4007') {
// msg = '관리자 승인 후 이용할 수 있습니다.';
vm.ModalOpen('modal03');
} else {
vm.$store.commit("login/isLogin", false);
return;
}
});
},
clickMenu(link){
this.$router.push({
path: link
});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
},
} //method 끝
};
</script>
<template>
<div class="wrap bg-wrap">
<div class="login-box adm-login">
<div class="wbox">
<div class="logo"></div>
<h3 class="title">관리자 로그인</h3>
<!-- <form action=""> -->
<div class="login-form">
<li><input type="text" placeholder="아이디" v-model="userId"></li>
<li><input type="password" placeholder="비밀번호" v-model="userPwd" @keyup.enter="ajaxlogin"></li>
<li>
<span class="lcont"><input type="checkbox" id="id-remember" ref="chkSaveId" checked><label for="id-remember">아이디 저장</label></span>
<span class="rcont"><button class="btn-pwreset" @click="clickMenu('/view/login/resetPassword')">비밀번호 초기화</button></span>
</li>
<li><button class="btn-pcolor" v-on:click="ajaxlogin">로그인</button></li>
</div>
<!-- </form> -->
<div class="login-notice">
<div>
<li>비밀번호 분실 비밀번호 초기화를 이용해주세요.</li>
<li>비밀번호는 90일이내 변경하여 안전히 관리해주세요.</li>
</div>
</div>
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
import api from '../service/api';
import LoginPopup from '@/components/LoginPopup.vue';
import tokenSvc from '@/common/token-service';
//import * as utils from '@/common/utils';
export default {
data: function() {
return {
errors: [],
corpId: '',
userId: '',
userPwd: ''
};
},
created() {
// 로그인 페이지 진입시
if(!!tokenSvc.getToken()){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.$router.push({ path: '/' });
}else{
this.$store.commit("login/isLogin", false);
this.$store.commit("login/isAuthChk", false);
this.$store.commit("login/isErrorPage", false);
}
},
mounted() {
this.$refs.chkSaveId.checked = true;
if (localStorage.hubwebUserId) {
this.userId = localStorage.hubwebUserId;
}
},
destroyed() {
let cont = document.querySelector(".wrap");
cont.classList.remove("login-wrap");
},
components: {
LoginPopup : LoginPopup
},
methods: {
chgChkUserId() {
if (this.$refs.chkSaveId.checked == true) {
localStorage.hubwebUserId = this.userId;
} else {
delete localStorage.hubwebUserId;
}
},
toRegister(){
this.$router.push({ name: 'register'});
},
formCheck: function() {
this.errors = [];
if (!this.userId) this.errors.push('아이디를 입력해 주세요.');
if (!this.userPwd) this.errors.push('비밀번호를 입력해 주세요.');
return this.errors.length == 0;
},
ajaxlogin: function() {
var vm = this;
vm.errmsg = null;
if (!vm.formCheck()) return false;
let oprtrPw = this.userPwd;
// FormData 객체를 파라미터로 넘기면 Content-Type: multipart/form-data; 요청을 한다.
// 일반 Object를 파라미터로 넘기면 Content-Type: application/json;charset=UTF-8 요청을 한다.
var params = {
"oprtrId": this.userId,
"oprtrPw": this.userPwd,
}
//로그인버튼을 누를시 상황
api.login(params).then(function(response) {
var rsp = response.data;
if(rsp.retCode == '0000'){
var path = rsp.data.nextUrl;
console.log(path);
vm.chgChkUserId();
vm.$store.commit("login/isLogin", true);
vm.$store.commit("login/savePwd", oprtrPw);
vm.$router.push({ path: '/view/login/auth'});
} else if(rsp.retCode == '4004') { // ID/PWD 불일치
vm.errors.push('로그인 실패하였습니다. (5회 실패 시 계정 잠김)');
vm.ModalOpen('modal01');
} else if(rsp.retCode == '4005') { // ID/PWD 불일치 횟수초과로 계정 잠김
// msg = '5회 이상 로그인 실패하여 해당 아이디에 대한 계정이 잠금처리되었습니다.\n관리자에게 문의하세요.';
vm.ModalOpen('modal02');
} else if(rsp.retCode == '4006') {
// msg = '비밀번호를 변경하신지 90일이 지났습니다.\n비밀번호 변경 화면으로 이동합니다.';
vm.chgChkUserId();
vm.ModalOpen('modal04');
} else if(rsp.retCode == '4007') {
// msg = '관리자 승인 후 이용할 수 있습니다.';
vm.ModalOpen('modal03');
} else {
vm.$store.commit("login/isLogin", false);
return;
}
});
},
clickMenu(link){
this.$router.push({
path: link
});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
},
} //method 끝
};
</script>

View File

@@ -1,97 +1,112 @@
<template>
<div class="wrap bg-wrap">
<!-- s: 패스워드초기화 -->
<div class="login-box pw-reset">
<div class="logo"></div>
<div class="wbox">
<h3 class="title">비밀번호 초기화</h3>
<!-- <form action=""> -->
<div class="login-form">
<div>
<input type="text" placeholder="아이디를 입력하세요"></div>
<div class="button_group">
<button class="btn-default" @click="clickMenu('/login')">취소</button>
<button class="btn-pcolor">비밀번호 초기화 문자 발송하기</button>
</div>
</div>
<!-- </form> -->
<div class="login-notice">
<div>
<li>초기화된 비밀번호는 등록된 휴대폰 문자메시지로 발송됩니다.</li>
<li>휴대폰 번호 변경 관리자로 문의해주세요.</li>
</div>
</div>
</div>
<div>
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
// import api from '../service/api';
import LoginPopup from '@/components/LoginPopup.vue';
export default {
name: 'resetPassword',
data() {
return {}
},
created() {
this.$store.commit("login/isLogin", false);
this.$store.commit("login/isAuthChk", false);
},
components: {
LoginPopup
},
methods: {
// ajaxReset: function(){
// var vm = this;
// vm.errmsg = null;
// // if (!vm.formCheck()) return false;
// var params = {
// //"corpId": this.corpId,
// // "userPwd": this.userPwd,
// } // 주석으로 인한
// api.newpwd(params).then(function(response){
// var rsp = response.data;
// console.log("RESULT_CODE : "+rsp.retCode);
// if(rsp.retCode == '000'){
// // vm.$store.commit("login/isLogin", true);
// //vm.$store.commit("login/isAuthChk", true);
// vm.ModalOpen('modal12');
// // vm.$router.push({ path : 'view/login'});
// } else {
// return;
// }
// });
// }
// ,
clickMenu(link) {
this
.$router
.push({path: link});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
},
}
}
</script>
<template>
<div class="wrap bg-wrap">
<!-- s: 패스워드초기화 -->
<div class="login-box pw-reset">
<div class="logo"></div>
<div class="wbox">
<h3 class="title">비밀번호 초기화</h3>
<!-- <form action=""> -->
<div class="login-form">
<div>
<input type="text" placeholder="아이디를 입력하세요" v-model="userId"></div>
<div class="button_group">
<button class="btn-pcolor" @click="ajaxReset">비밀번호 초기화 문자 발송하기</button>
<button class="btn-default" @click="clickMenu('/login')">취소</button>
</div>
</div>
<!-- </form> -->
<div class="login-notice">
<div>
<li>초기화된 비밀번호는 등록된 휴대폰 문자메시지로 발송됩니다.</li>
<li>휴대폰 번호 변경 관리자로 문의해주세요.</li>
</div>
</div>
</div>
<div>
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
import api from '../service/api';
import LoginPopup from '@/components/LoginPopup.vue';
export default {
name: 'resetPassword',
data: function() {
return {
errors: [],
userId: '',
}
},
created() {
this.$store.commit("login/isLogin", false);
this.$store.commit("login/isAuthChk", false);
},
components: {
LoginPopup
},
methods: {
formCheck: function()
{
this.errors = [];
if (!this.userId) {
this.errors.push('아이디를 입력해 주세요.');
}
return this.errors.length == 0;
},
ajaxReset: function(){
var vm = this;
//vm.errmsg = null;
if (!vm.formCheck()) return false;
var params =
{
"userId": this.userId,
//"userPwd": this.userPwd,
}
api.resetPassword(params).then(function(response){
var rsp = response.data;
console.log("RESULT_CODE : "+rsp.retCode);
if(rsp.retCode == '0000'){
// vm.$store.commit("login/isLogin", true);
//vm.$store.commit("login/isAuthChk", true);
vm.ModalOpen('modal12');
// vm.$router.push({ path : 'view/login'});
} else if(rsp.retCode == '4003') {
vm.ModalOpen('modal13');
} else {
return;
}
});
}
,
clickMenu(link) {
this
.$router
.push({path: link});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
},
}
}
</script>
<style></style>

View File

@@ -0,0 +1,163 @@
<template>
<div class="wrap bg-wrap">
<!-- s: 비밀번호변경 -->
<div id="cpf" class="login-box pw-change">
<div class="logo"></div>
<div class="wbox">
<h3 class="title">비밀번호 변경</h3>
<p class="desc">임시비밀번호로 로그인할 경우 비밀번호를 변경 <br>서비스 이용이 가능합니다.</p>
<form @submit.prevent="changedPwd">
<ul class="pw-form">
<div><input id="oldPw" type="text" placeholder="기존 비밀번호를 입력하세요" v-model="oldPw" ref="oldPw"></div>
<div>
<input id="newPw" type="text" placeholder="새로운 비밀번호를 입력하세요" v-model="newPw" ref="newPw" maxlength="16">
</div>
<div><input type="text" placeholder="새로운 비밀번호를 다시 한 번 입력하세요" ></div>
<div><button class="btn-pcolor" @click="changedPwd()">비밀번호 변경하기</button></div>
</ul>
</form>
</div>
</div>
<login-popup ref="LoginPopup"> </login-popup>
</div>
</template>
<script>
import api from '../service/api';
import { mapGetters } from 'vuex';
import LoginPopup from '@/components/LoginPopup.vue';
import tokenSvc from '@/common/token-service';
import { commonPwdView, validation } from '../service/mixins';
// import { chkPattern } from '@/common/vue-mixins';
// import * as utils from '@/common/utils';
export default {
mixins: [commonPwdView, validation],
data: function() {
return {
userId: '',
oldPw: '',
newPw: '',
passwordValidFlag: true,
};
},
created: function() {
if(!!tokenSvc.getToken()){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.$router.push({ path: '/' });
}else{
// if(!this.getLogin){
// this.$router.push({ path: '/login' });
// }
}
},
mounted() {
// this.$refs.chkSaveId.checked = true;
if (localStorage.hubwebUserId) {
this.userId = localStorage.hubwebUserId;
}
this.isLogin = this.getLogin;
this.oldPw = this.getPwd;
},
computed: {
...mapGetters({
getLogin: 'login/isLogin',
getPwd: 'login/getPwd'
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
getPwd(data) {
if(data != null && data != ''){
this.pwd = data;
}
}
},
components: {
LoginPopup : LoginPopup
},
methods: {
verifyNewPw: function() {
this.message.newPw = '';
},
formCheck: function() {
this.errors = [];
if (!this.oldPw) this.errors.push('기존비밀번호');
if (!this.newPw) this.errors.push('새로운비밀번호');
return this.errors.length == 0;
},
changedPwd: function() {
var vm = this;
var params = {
"userId": this.userId,
"oldPw": this.oldPw,
"newPw": this.newPw
}
api.updatePassword(params).then(function(response) {
var rsp = response.data;
// var pofo = document.getElementById('oldPw');
if(rsp.retCode == '0000') {
// vm.chgChkUserId();
if(vm.ModalOpen('modal16')){
vm.$router.push({ path: '/login' });
}
} else if(rsp.retCode == '4016') {
vm.ModalOpen('modal14')
} else if(rsp.retCode == '4017') {
vm.ModalOpen('modal15')
} else if(rsp.retCode == '4003') {
if(vm.ModalOpen('modal14')) {
//수정사항 : 모달오픈 -> 기존비밀번호 포커스
alert('1');
}
// //this.$refs.oldPw.focus();
// alert('비밀번호 유효성체크');
// vm.$refs.oldPw.focus();
}
else {
return;
}
});
},
ModalOpen: function(target){
this.$refs.LoginPopup.ModalOpen(target);
// this.$refs.oldPw.focus(target);
},
}
}
</script>

View File

@@ -0,0 +1,273 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">관리자/유치채널 관리</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right" v-model="grid.params.searchType1" @keyup.enter="search">
<option value="">전체</option>
<option v-for="(option, i) in authType" v-bind:value="option.autCd" v-bind:key="i">
{{ option.autNm }}
</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="" v-model="grid.params.searchType2" @keyup.enter="search">
<option value="" selected>전체</option>
<option v-for="(option, i) in statType" v-bind:value="option.code" v-bind:key="i">
{{ option.codeNm }}
</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력" v-model="grid.params.searchText1" @keyup.enter="search"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력" v-model="grid.params.searchText2" @keyup.enter="search"/>
</div>
<button type="button" class="button grey" @click="search">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>{{ totalItems }}</span></div>
<div class="button_group">
<button type="button" class="button blue admin add" @click="adminRegPopOpen();">관리자 등록</button>
<button type="button" class="button blue channel add" @click="adminReg2PopOpen();">유치채널 등록</button>
<button type="button" class="button white delete del" @click="deleteRow();">삭제</button>
</div>
</div>
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="grid.url"
:pagePerRows="grid.pagePerRows"
:initialRequest="grid.initialRequest"
:pagination="grid.pagination"
:isCheckbox="grid.isCheckbox"
:columns="grid.columns"
:noDataStr="grid.noDataStr"
:addCls="grid.addCls"
:header="grid.headder"
></custom-grid>
</div>
<admin-reg-pop ref="adminRegModal"> </admin-reg-pop>
<!-- <admin-reg2-pop ref="adminReg2Modal"> </admin-reg2-pop> -->
<admin-detail-pop ref="adminDetailModal"> </admin-detail-pop>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
import AdminRegPop from '../components/AdminRegPop';
//import AdminReg2Pop from '../components/AdminReg2Pop';
import AdminDetailPop from '../components/AdminDetailPop';
import api from '@/service/api.js';
import sysMgtApi from "../service/sysMgtApi.js";
class CustomATagRenderer {
constructor(props) {
this.props = props;
const el = document.createElement('a');
el.href = 'javascript:void(0);';
el.className = 'btn_text';
el.innerText= String(props.colValue)
this.el = el;
}
getElement() {
return this.el;
}
addEvent(selEl) {
selEl.addEventListener("click", () => {
const { callback } = this.props["cgrido" + this.props.colName].options;
callback(this.props);
});
}
}
export default {
name: 'adminList',
data() {
return {
row: {},
authType: [],
statType: [],
cate2Code: "",
totalItems: 0,
// 테이블 리스트 데이터
perPageCnt: 20,
grid: {
url: '/api/v1/bo/sysMgt/adminList',
pagePerRows: 20,
pagination: true,
isCheckbox: true, // true:첫번째 컬럼 앞에 체크박스 생성 / false:체크박스 제거
initialRequest: false,
addCls: 'box_OFvis',
columns: [
{ name: 'no', header: 'No', align: 'center', width: 60},
{ name: 'auth', header: '권한', align: 'center', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130, renderer: {
type: CustomATagRenderer
, options: {
callback: this.detailPop,
}
}
},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130, cls: 'td_line'},
{ name: 'regDt', header: '등록일', align: 'center', width: 130}
],
noDataStr: '검색 결과가 없습니다.',
params: {
searchType1: '',
searchType2: '',
searchText1: '',
searchText2: ''
},
excelHeader: []
}
};
},
components: {
customGrid: customGrid,
// SystemPopup,
AdminRegPop,
//AdminReg2Pop,
AdminDetailPop
},
created(){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.setCodeData();
//let cont = document.querySelector(".wrap");
//cont.classList.add("main_wrap");
},
destroyed() {
},
mounted() {
let page = 1;
// 페이지 정보 및 검색 조건
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
console.log('getCondition : '+getCondition);
// store에 저장된 페이지 정보 및 검색 조건을 불러오기
let isKeep = false;
if (getCondition) {
this.grid.pagePerRows = getCondition.perPage;
this.grid.params = getCondition.params;
page = getCondition.page;
isKeep = true;
}
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log('this.perPageCnt'+this.perPageCnt);
//console.log(this.grid.params);
this.$refs.table.search(this.grid.params, isKeep);
this.sendStoreData();
},
detailPop(props) {
// this.getMainSlot().popupView(4);
// this.setDtlPpPrm(props);
this.$refs.adminDetailModal.adminDetailModalOpen(props);
},
ModalOpen: function(target){
//this.$refs.systemModal.ModalOpen(target);
},
adminRegPopOpen: function(){
this.$refs.adminRegModal.ModalOpen(1);
},
adminReg2PopOpen: function(){
this.$refs.adminRegModal.ModalOpen(2);
//this.$refs.adminReg2Modal.adminReg2ModalOpen();//
},
doValidate(){ //로우데이터 삭제하도록 수정
console.log("totalItems >> " + this.totalItems);
if(this.totalItems == 0){
alert('검색 결과가 없습니다.');
return false;
}
var chkList = this.$refs.table.checkedElementDatas();
if(chkList.length == 0){
alert('체크박스에 체크를 해주세요.');
return false;
}
// for(var i = 0; i < chkList.length; i++){
// alert(chkList[i].adminId);
// }
const param = chkList.map((row)=>({adminId:row.adminId}));
this.row.list = param;
console.log(this.row);
return true;
},
sendStoreData: function() {
const getP = this.$refs.table.getPagination();
console.log("==========getP : " + getP);
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params
});
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
//console.log("getCondition : "+ getCondition.perPage);
},
setCodeData() {
// 상태 옵션 셋팅.
api.commCode({'grpCd' : 'ADM_STTUS_CD'}).then(response => {
this.statType = response.data.data.list;
});
api.commAuth().then(response => {
this.authType = response.data.data.list;
});
},
async deleteRow(){
if(this.doValidate() && window.confirm('삭제 하시겠습니까?')){
try {
let response = await sysMgtApi.deleteAdmin(this.row);
const result = response.data;
if (result != null && result.retCode == "0000") {
alert('삭제 하였습니다.');
// grid.reloadData();
this.$refs.table.reloadData();
return;
}
alert("실패 하였습니다.");
} catch(err) {
alert("실패 하였습니다.");
}
}
},
},
beforeRouteLeave(to, from, next) {
const getP = this.$refs.table.getPagination();
console.log("==========getP : " + getP._currentPage);
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params
});
// 라우트 하기전 실행
next();
}
};
</script>

View File

@@ -0,0 +1,107 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">권한 관리</h3>
<p class="breadcrumb">시스템관리 &gt; 권한 관리</p>
</div>
<div class="info">
<div class="count"> <span>4</span></div>
<div class="button_group">
<button type="button" class="button blue add" onclick="location.href='system_right_add.html';">권한 추가</button>
</div>
</div>
<div class="table">
<table>
<colgroup>
<col width="10%"/>
<col width="20%"/>
<col width="20%"/>
<col width="15%"/>
<col width="20%"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th>NO</th>
<th>코드</th>
<th>권한명</th>
<th>상태</th>
<th>등록일</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey" onclick="location.href='system_right_modify.html';">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>3</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>2</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>1</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'authList',
data() {
return {
};
},
components: {
},
destroyed() {
},
mounted() {
},
methods: {
}
};
</script>

View File

@@ -0,0 +1,237 @@
<template>
<div>
<div class="dimmed modal21" @click="adminDetailModalClose();"></div>
<div class="popup-wrap modal21">
<!-- 관리자/유치채널 상세정보 -->
<div class="popup modal21 popup_form">
<div class="pop-head">
<h3 class="pop-tit" v-if="code === null || code === ''">관리자 상세정보</h3>
<h3 class="pop-tit" v-else>유치채널 상세정보</h3>
</div>
<form autocomplete="off" ref="adminDetailForm">
<table>
<tbody>
<tr>
<th>ID</th>
<td><input type="text" disabled v-model.trim="madangId" ref="_madangId2"></td>
</tr>
<tr>
<th>비밀번호</th>
<td><input type="password" @keypress="onlyPassword" @input="onlyPassword" required minlength="8" maxlength="16" ref="_pwd1" v-model.trim="userPwd1"></td>
</tr>
<tr>
<th>비밀번호 확인</th>
<td><input type="password" @keypress="onlyPassword" @input="onlyPassword" required minlength="8" maxlength="16" ref="_pwd2" v-model.trim="userPwd2"></td>
</tr>
<tr>
<th>이름</th>
<td><input type="text" disabled v-model.trim="userNm" ref="_userNm"></td>
</tr>
<tr>
<th>휴대폰번호</th>
<td><input type="number" disabled v-model.trim="mdn" ref="_phone"></td>
</tr>
<tr>
<th>이메일</th>
<td><input type="email" disabled v-model.trim="email" ref="_email"></td>
</tr>
<tr>
<th>권한</th>
<td v-if="code === null || code === ''">
<div v:class="select_box">
<select name="" id="right" v-model="auth" ref="_auth">
<option value="">선택</option>
<option
v-for="(option, i) in authType"
v-bind:value="option.autCd"
v-bind:key="i"
:selected="auth === option.autCd">
{{ option.autNm }}
</option>
</select>
</div>
</td>
<td v-else><input type="text" disabled value="대리점"></td>
</tr>
<tr>
<th class="center">상태</th>
<td>
<input type="radio" name="state" value="01" id="popup_radio1"
v-model="stat"
:checked="stat == '1'">
<label for="popup_radio1">사용</label>
<input type="radio" name="state" value="02" id="popup_radio2"
v-model="stat"
:checked="stat == '02'">
<label for="popup_radio2">정지</label>
</td>
</tr>
</tbody>
</table>
</form>
<div class="pop-btn2">
<button class="btn-default" @click="adminDetailModalClose();">취소</button>
<button class="btn-pcolor" @click="doInsert">저장</button>
</div>
</div>
<!-- 관리자 상세정보 팝업 -->
</div>
</div>
</template>
<script>
import api from '@/service/api';
import sysMgtApi from "../service/sysMgtApi.js";
import { utils_mixin, chkPattern2 } from '../service/mixins';
import lodash from "lodash";
export default {
name: "adminDetailPop",
mixins: [utils_mixin, chkPattern2],
watch:{
stat(){
console.log('watch : ', this.stat)
}
},
data(){
return{
row: {},
authType: [],
madangId:'',
name:'',
mdn:'',
email:'',
auth:'',
stat: '',
userNm:"",
userPwd1:"",
userPwd2:"",
code:"",
}
},
model: {
prop: 'sendData',
event: 'event-data'
},
props: ['sendData'],
created(){
//this.formReset();
this.setAuthData();
},
methods :{
doPwdValidate(){
if(this.isNull(this.userPwd2)){
alert("비밀번호 확인을 입력해 주세요.");
this.$refs._pwd2.focus();
return false;
}
if(!lodash.isEqual(this.userPwd1, this.userPwd2)){
alert("비밀번호가 일치하지 않습니다.");
this.$refs._pwd2.focus();
return false;
}
const pwdLen = this.bytes(this.userPwd1);
if(!(pwdLen >= 8 && pwdLen <= 16)){
alert("비밀번호는 8~16자의 영문, 숫자, 특수문자(!,@, $, %, ^, &, *) 조합이 필요합니다.");
this.$refs._pwd1.focus();
return false;
}
const pEng = /[A-Za-z]/g; // 영문자
const pNum = /[0-9]/g; // 숫자
const pSpc = /[!@$%^&*]/g; // 특수문자
if(!(pEng.test(this.userPwd1) && pNum.test(this.userPwd1) && pSpc.test(this.userPwd1))) {
alert("비밀번호는 8~16자의 영문, 숫자, 특수문자(!,@, $, %, ^, &, *) 조합이 필요합니다.");
this.$refs._pwd1.focus();
return;
}
this.row.adminPw=this.userPwd1;
return true;
},
doValidate(){
if(!this.isNull(this.userPwd1)){
if(!this.doPwdValidate()){
return false;
}
}
if(!this.isNull(this.auth)){
if(this.code == ''){
this.row.auth = this.auth;
}else{
this.row.auth=this.auth;
}
}
if(!this.isNull(this.stat)){
this.row.stat=this.stat;
}
this.row.adminId=this.madangId;
return true;
},
// 모달 띄우기
async adminDetailModalOpen(props){
this.row.adminId = props.adminId;
try {
const response = await sysMgtApi.adminDetail(this.row);
const result = response.data;
console.log(result);
if (result != null && result.retCode == "0000") {
this.madangId = result.data.adminId;
this.auth = result.data.auth;
this.userNm = result.data.name;
this.email = result.data.email;
this.mdn = result.data.mdn;
this.stat = result.data.stat;
}
} catch(err) {
alert("실패 하였습니다.");
}
var dimmed = document.getElementsByClassName('modal21');
for(var i = 0; i < dimmed.length; i++){
dimmed[i].style.display = 'block';
}
},
// 모달 끄기
adminDetailModalClose(){
this.formReset();
var dimmed = document.getElementsByClassName('modal21');
for(var i = 0; i < dimmed.length; i++){
dimmed[i].style.display = 'none';
}
},
toComplete(){
this.getParent('adminList').$refs.table.reloadData();
this.adminDetailModalClose();
},
async doInsert(){
if(this.doValidate() && window.confirm('등록 하시겠습니까?')){
try {
const response = await sysMgtApi.updateAdmin(this.row);
const result = response.data;
if (result != null && result.retCode == "0000") {
alert('저장 하였습니다.');
this.toComplete();
}
} catch(err) {
alert("실패 하였습니다.");
}
}
},
setAuthData() {
// 권한 옵션.
api.commAuth().then(response => {
this.authType = response.data.data.list;
});
},
formReset(){
this.$refs.adminDetailForm.reset();
},
}
}
</script>
<style>
.popup-btn-wrap {width: 500px; margin: auto; padding: 100px 0;}
.popup-btn-wrap button {width: 100%; margin-bottom: 10px; height: 50px; border-radius: 5px; box-shadow: none; border: 1px solid #000; }
.popup-btn-wrap button:hover {background: #000; color: #fff;}
</style>

View File

@@ -0,0 +1,265 @@
<template>
<!-- <div class="wrap bg-wrap"> -->
<div>
<div class="dimmed" @click="ModalClose();"></div>
<div class="popup-wrap">
<!-- 관리자/유치채널 등록 -->
<div class="popup modal20 popup_form">
<div class="pop-head">
<h3 class="pop-tit" v-if="insertType === 1">관리자 등록</h3>
<h3 class="pop-tit" v-else>유치채널 사용자 등록</h3>
</div>
<form autocomplete="off" ref="adminRegForm">
<table>
<tbody>
<tr>
<th>마당 ID</th>
<td class="input_search">
<input type="text" placeholder="아이디 입력" v-model.trim="madangId" ref="madangId">
<button type="button" class="button grey" >조회</button>
</td>
</tr>
<tr>
<th>비밀번호</th>
<td><input type="password" @keypress="onlyPassword" @input="onlyPassword" required minlength="8" maxlength="16" ref="_pwd1" v-model.trim="userPwd1"></td>
</tr>
<tr>
<th>비밀번호 확인</th>
<td><input type="password" @keypress="onlyPassword" @input="onlyPassword" required minlength="8" maxlength="16" ref="_pwd2" v-model.trim="userPwd2"></td>
</tr>
<tr>
<th>이름</th>
<td><input type="text" @keypress="onlyName" @input="onlyName" v-model.trim="userNm" ref="_userNm" required maxlength="40"></td>
</tr>
<tr>
<th>휴대폰번호</th>
<td><input type="number" placeholder="- 자 제외 숫자만 입력" v-model.trim="mdn" v-on:keyup="onlyNum" @input="onlyNum" minlength="10" maxlength="11" ref="_phone"></td>
</tr>
<tr>
<th>이메일</th>
<td><input type="email" v-model.trim="email" @keypress="onlyEmail" @input="onlyEmail" maxlength="20" ref="_email"></td>
</tr>
<tr v-if="insertType === 2">
<th>코드</th>
<td><input type="text" disabled ref="_code" v-model.trim="code"></td>
</tr>
<tr>
<th>권한</th>
<td v-if="insertType === 1">
<div v:class="select_box">
<select name="" id="right" v-model="auth" ref="_auth">
<option value="">선택</option>
<option v-for="(option, i) in authType" v-bind:value="option.autCd" v-bind:key="i">
{{ option.autNm }}
</option>
</select>
</div>
</td>
<td v-else><input type="text" disabled value="대리점"></td>
</tr>
<tr>
<th class="center">상태</th>
<td>
<input type="radio" name="state" value="01" id="popup_radio1" v-model="stat">
<label for="popup_radio1">사용</label>
<input type="radio" name="state" value="02" id="popup_radio2" v-model="stat">
<label for="popup_radio2">정지</label>
</td>
</tr>
</tbody>
</table>
</form>
<div class="pop-btn2">
<button class="btn-default" @click="ModalClose();">취소</button>
<button class="btn-pcolor" @click="doInsert">저장</button>
</div>
</div>
</div>
</div>
</template>
<script>
import api from '@/service/api';
import sysMgtApi from "../service/sysMgtApi.js";
import { utils_mixin, chkPattern2 } from '../service/mixins';
import lodash from "lodash";
export default {
name: "adminRegPop",
mixins: [utils_mixin, chkPattern2],
watch:{
stat(){
console.log('watch : ', this.stat)
}
},
data(){
return{
row: {},
authType: [],
insertType:0,
madangId:'',
name:'',
mdn:'',
email:'',
auth:'',
stat: '',
userNm:"",
userPwd1:"",
userPwd2:"",
code:"",
}
},
model: {
prop: 'sendData',
event: 'event-data'
},
props: ['sendData'],
created(){
this.formReset();
this.setAuthData();
},
methods :{
doPwdValidate(){
if(this.isNull(this.userPwd1)){
alert("비밀번호를 입력해 주세요.");
this.$refs._pwd1.focus();
return false;
}
if(this.isNull(this.userPwd2)){
alert("비밀번호 확인을 입력해 주세요.");
this.$refs._pwd2.focus();
return false;
}
if(!lodash.isEqual(this.userPwd1, this.userPwd2)){
alert("비밀번호가 일치하지 않습니다.");
this.$refs._pwd2.focus();
return false;
}
const pwdLen = this.bytes(this.userPwd1);
if(!(pwdLen >= 8 && pwdLen <= 16)){
alert("비밀번호는 8~16자의 영문, 숫자, 특수문자(!,@, $, %, ^, &, *) 조합이 필요합니다.");
this.$refs._pwd1.focus();
return false;
}
const pEng = /[A-Za-z]/g; // 영문자
const pNum = /[0-9]/g; // 숫자
const pSpc = /[!@$%^&*]/g; // 특수문자
if(!(pEng.test(this.userPwd1) && pNum.test(this.userPwd1) && pSpc.test(this.userPwd1))) {
alert("비밀번호는 8~16자의 영문, 숫자, 특수문자(!,@, $, %, ^, &, *) 조합이 필요합니다.");
this.$refs._pwd1.focus();
return;
}
this.row.adminPw=this.userPwd1;
return true;
},
doValidate(){
if(!this.doPwdValidate()){
return false;
}
if(this.isNull(this.userNm)){
alert("이름을 입력해 주세요");
this.$refs._userNm.focus();
return false;
}
if(this.isNull(this.mdn)){
alert('휴대폰번호를 입력해주세요.');
this.$refs._phone.focus();
return false;
}
const hp = this.mdn;
if(!this.isNull(hp) && !this.isMobile(hp)){
alert("휴대폰 번호 형식이 잘못되었습니다. 확인해 주세요");
this.$refs._phone.focus();
return false;
}
if(this.isNull(this.email)){
alert('이메일을 입력해주세요.');
this.$refs._email.focus();
return false;
}
const email = this.email;
if(!this.isNull(email) && !lodash.isEqual(email,'@') && !this.emailCheck(email)){
alert("이메일 형식이 잘못되었습니다. 확인해 주세요");
this.$refs._email.focus();
return false;
}
if(this.isNull(this.auth)){
alert('권한을 선택 해주세요.');
this.$refs._auth.focus();
return false;
}
if(this.isNull(this.stat)){
alert('상태를 선택 해주세요.');
// this.$refs._auth.focus();
return false;
}
this.row.madangId=this.madangId;
this.row.name=this.userNm;
this.row.mdn=hp;
this.row.email=email;
if(this.insertType == 2){
this.row.auth='1003';
}else{
this.row.auth=this.auth;
}
this.row.stat=this.stat;
return true;
},
// 모달 띄우기
ModalOpen(insertType){
this.insertType=insertType;
var dimmed = document.getElementsByClassName('dimmed');
dimmed[0].style.display = 'block';
var wrap = document.getElementsByClassName('popup-wrap');
wrap[0].style.display = 'block';
var obj = document.getElementsByClassName('modal20');
obj[0].style.display = 'block';
},
// 모달 끄기
ModalClose(){
this.formReset();
var dimmed = document.getElementsByClassName('dimmed');
dimmed[0].style.display = 'none';
var wrap = document.getElementsByClassName('popup-wrap');
wrap[0].style.display = 'none';
var popup = document.getElementsByClassName('modal20');
popup[0].style.display = 'none';
},
// 저장 후 부모창 호출.
toComplete(){
this.getParent('adminList').$refs.table.reloadData();
this.ModalClose();
},
async doInsert(){
if(this.doValidate() && window.confirm('등록 하시겠습니까?')){
try {
const response = await sysMgtApi.insertAdmin(this.row);
const result = response.data;
if (result != null && result.retCode == "0000") {
alert('저장 하였습니다.');
this.toComplete();
}
} catch(err) {
alert("실패 하였습니다.");
}
}
},
setAuthData() {
// 권한 옵션.
api.commAuth().then(response => {
this.authType = response.data.data.list;
});
},
formReset(){
this.$refs.adminRegForm.reset();
},
}
}
</script>
<style>
.popup-btn-wrap {width: 500px; margin: auto; padding: 100px 0;}
.popup-btn-wrap button {width: 100%; margin-bottom: 10px; height: 50px; border-radius: 5px; box-shadow: none; border: 1px solid #000; }
.popup-btn-wrap button:hover {background: #000; color: #fff;}
</style>

View File

@@ -1,18 +1,18 @@
import AustList from '../views/AuthList'
import AdminList from '../views/AdminList'
export default [
{
path: '/sysMgt/authList',
component: AustList,
name: 'authList',
meta: { public: true }
},
{
path: '/sysMgt/adminList',
component: AdminList,
name: 'adminList',
meta: { public: true }
}
]
import AustList from '../views/AuthList'
import AdminList from '../views/AdminList'
export default [
{
path: '/sysMgt/authList',
component: AustList,
name: 'authList',
meta: { public: true }
},
{
path: '/sysMgt/adminList',
component: AdminList,
name: 'adminList',
meta: { public: true }
}
]

View File

@@ -0,0 +1,353 @@
import lodash from "lodash";
const utils_mixin = {
methods:{
/** * 이메일 형식 체크 * * @param 데이터 */
emailCheck(email,rtnArrYn) {
if(this.isNull(rtnArrYn)){
rtnArrYn='N';
}
// var regExp = /(^[A-Za-z0-9_\.\-]+)@([A-Za-z0-9\-]+\.[A-Za-z0-9\-]+)/;
var regExp = /^([0-9a-zA-Z_\.\-]([-_.]?[0-9a-zA-Z_\.\-])*)@([0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$)/i;//이메일 정규식
if(regExp.test(email) == false) {
// 이메일 형식이 알파벳+숫자@알파벳+숫자.알파벳+숫자 형식이 아닐경우
if(rtnArrYn == 'Y'){
return email;
}
return false;
}else{
var myArray = regExp.exec(email);
if(rtnArrYn == 'Y'){
return myArray;
}
return true;
}
},
/** * 전화번호 포맷으로 변환 * * @param 데이터 */
formatPhone(phoneNum,fmt,rtnArrYn) {
if(this.isNull(fmt)){
fmt='';
}
if(this.isNull(rtnArrYn)){
fmt='N';
}
if(this.isPhone(phoneNum)) {
var rtnNum;
var regExp =/(02)([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
rtnNum = myArray[1]+fmt + myArray[2]+fmt+myArray[3];
if(rtnArrYn == 'Y'){
return myArray;
}
return rtnNum;
} else {
regExp =/(0[3-9]{1}[0-9]{1})([0-9]{3,4})([0-9]{4})$/;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
rtnNum = myArray[1]+fmt+myArray[2]+fmt+myArray[3];
if(rtnArrYn == 'Y'){
return myArray;
}
return rtnNum;
} else {
return phoneNum;
}
}
} else {
return phoneNum;
}
},
/** * 핸드폰번호 포맷으로 변환 * * @param 데이터 */
formatMobile(phoneNum,fmt,rtnArrYn) {
if(this.isNull(fmt)){
fmt='';
}
if(this.isNull(rtnArrYn)){
fmt='N';
}
if(this.isMobile(phoneNum)) {
var rtnNum;
var regExp =/(01[016789])([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
rtnNum = myArray[1]+fmt+myArray[2]+fmt+myArray[3];
if(rtnArrYn == 'Y'){
return myArray;
}
return rtnNum;
} else {
return phoneNum;
}
} else {
return phoneNum;
}
},
/** * 전화번호 형식 체크 * * @param 데이터 */
isPhone(phoneNum) {
var regExp =/(02)([0-9]{3,4})([0-9]{4})$/;
if(regExp.test(phoneNum)){
return true;
} else {
regExp =/(0[3-9]{1}[0-9]{1})([0-9]{3,4})([0-9]{4})$/;
if(regExp.test(phoneNum)){
return true;
} else {
return false;
}
}
},
/** * 핸드폰번호 형식 체크 * * @param 데이터 */
isMobile(phoneNum) {
var regExp =/(01[016789])([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
return true;
} else {
return false;
}
},
isMobile2(phoneNum) {
var regExp =/(1[016789])([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
return true;
} else {
return false;
}
},
isNull(obj){
if(lodash.isNil(obj) || lodash.trim(obj) == ''){
return true;
}
return false;
},
getParent(name){
let p = this.$parent;
while(typeof p !== 'undefined'){
if(p.$options.name == name) {
return p;
}else {
p = p.$parent;
}
}
return false;
},
getJsonObj(str){
return JSON.parse(JSON.stringify(str));
},
}
};
var chkPattern2 = {
data: function () {
return {
}
},
methods: {
selSesStorage(keyLike){
if(this.isNull(keyLike)){
return null;
}
if(sessionStorage.length > 0){
let keyList = [];
for(let i=0;i<sessionStorage.length;i++){
const keyNm = sessionStorage.key(i);
if(keyNm.indexOf(keyLike) > -1){
keyList.push({name : keyNm, value : sessionStorage.getItem(keyNm)});
}
}
if(keyList.length > 0){
return keyList;
}
return null;
}
return null;
},
delSesStorage(keyList){
if(this.isNull(keyList)){
return null;
}
if(keyList.length > 0){
keyList.map((o) => (sessionStorage.removeItem(o.name)));
return true;
}
},
setGridMouseDownActive(){
const ele = document.querySelector(`div.tui-grid-container.tui-grid-show-lside-area`);
if(window.getEventListeners(ele).mousedown){
ele.removeEventListener('mousedown',window.getEventListeners(ele).mousedown[0].listener);
}
},
restrictChars : function($event,regExp,hanYn){
if(this.isNull(hanYn)){
hanYn='N';
}
if(hanYn === 'N' && $event.type === 'keydown'){
if($event.keyCode === 229){
$event.preventDefault();
return false;
}
}
if($event.type === 'keypress'){
//한글 처리 불가
if(regExp.test(String.fromCharCode($event.charCode))) {
return true;
}else{
$event.preventDefault();
return false;
}
}
if(hanYn === 'N' && ( $event.type === 'keyup' || $event.type === 'input' || $event.type === 'change' || $event.type === 'blur')){
$event.target.value = $event.target.value.replace(/[ㄱ-ㅎㅏ-ㅣ가-힣]/g,'');
$event.preventDefault();
return false;
}
return true;
},
setLenth: function (e, len) {
this.cut(e, len);
},
onlyCustom: function (e,strRegExp,hanYn) {
var regExp_g = new RegExp(strRegExp,'g');
this.cut(e);
return this.restrictChars(e,regExp_g,hanYn);
},
onlyCommon: function(strRegExp, e, len, isEventCall, hanYn) {
var regExp_g = new RegExp(strRegExp,'g');
if(isEventCall === 'N'){
if(!this.cut(e, len, isEventCall)){
return false;
}
if(!regExp_g.test(e.value)){
return false;
}
return true;
}
this.cut(e, len);
return this.restrictChars(e,regExp_g,hanYn);
},
onlyNum: function (e, len, isEventCall) {
var strRegExp = '^[0-9]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyEng: function (e, len, isEventCall) {
var strRegExp = '^[A-Za-z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyLowerEng: function (e, len, isEventCall) {
var strRegExp = '^[a-z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyUpperEng: function (e, len, isEventCall) {
var strRegExp = '^[A-Z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyEmail: function (e, len, isEventCall) {
var strRegExp = '^[a-zA-Z0-9_\.\-@._-]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyName: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyTitle: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyText: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9_-]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyPassword: function (e, len, isEventCall) {
var strRegExp = '^[A-Za-z0-9!@#$%^&*]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyId: function (e, len, isEventCall) {
var strRegExp = '^[A-Za-z0-9_\.\-]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyIp: function (e, len, isEventCall) {
var strRegExp = '^[0-9,.*]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyRoleNm_Space: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyRoleId_UnderBar: function (e, len, isEventCall) {
var strRegExp = '^[a-zA-Z0-9_]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
cut: function (ele, len, isValidChk) {
let e=ele;
if (typeof ele.target != "undefined") {
e=ele.target;
}
let max = this.isNull(len) ? e.attributes.maxlength.value : len;
let str = e.value;
if (this.bytes(str) > max) {
if(this.isNull(isValidChk)){
e.value = this.cutBytes(str, max);
}
return false;
}
return true;
},
cutBytes: function (str, len) {
while(1 === 1){
if(this.bytes(str) <= len){
return str;
}
str = str.slice(0,-1);
}
},
bytes: function (str) {
var length = ((s,b,i,c) => {
// for(b=i=0;c=s.charCodeAt(i++);b+=c>>11?3:c>>7?2:1); // 한글 3바이트
// for(b=i=0;c=s.charCodeAt(i++);b+=c>>11?2:c>>7?1:1); //한글 2바이트
b=0,i=0;
while(1 === 1){
c = s.charCodeAt(i++);
if (isNaN(c)) {
break;
}
b += c >> 11 ? 2 : c >> 7 ? 1 : 1;
}
return b
})(str);
return length;
},
checkPhone: function(str) {
str = str.replace(/[-\s]+/g, '');
if (str.charAt(0)!="0"){
str = "0"+str;
}
if (str.length<10||str.length>12){return "";}
if (isNaN(str)){return ""; }
if (str.substr(0,2)!="01" && str.substr(0,3)!="070" && str.substr(0,4)!="0505" && str.substr(0,4)!="0503"){return ""; }
return str;
},
}
};
export { utils_mixin, chkPattern2 };

View File

@@ -0,0 +1,28 @@
import httpClient from '@/common/http-client';
// HUBEZ_BO_API_4003 - 관리자 등록.
const insertAdmin = (params) => {
return httpClient.post('/api/v1/bo/sysMgt/insertAdmin', params, { withCredentials: false });
}
// HUBEZ_BO_API_4004 - 관리자 수정.
const updateAdmin = (params) => {
return httpClient.post('/api/v1/bo/sysMgt/updateAdmin', params, { withCredentials: false });
}
// HUBEZ_BO_API_4005 - 관리자 삭제
const deleteAdmin = (params) => {
return httpClient.post('/api/v1/bo/sysMgt/deleteAdmin', params, { withCredentials: false });
}
// HUBEZ_BO_API_4006 - 관리자 정보 상세 조회.
const adminDetail = (params) => {
return httpClient.post('/api/v1/bo/sysMgt/adminDetail', params, { withCredentials: false });
}
export default {
insertAdmin,
updateAdmin,
deleteAdmin,
adminDetail
}

View File

@@ -0,0 +1,373 @@
import lodash from "lodash";
import moment from "moment";
import '@/modules/mgt/components/eventlisteners.js';
const filter_mixin = {
filters: {
_yyyy_mm_dd(val){
if(lodash.isNil(val) || lodash.trim(val) == '') return '';
const orgin = val;
if(orgin.length < 8) {
return orgin;
}
if(!Number(orgin)) return orgin;
const date = orgin.substring(0,8);
if(moment(date).isValid()){
return moment(date).format('YYYY[-]MM[-]DD');
}
return orgin;
}
},
}
const utils_mixin = {
methods:{
/** * 이메일 형식 체크 * * @param 데이터 */
emailCheck(email,rtnArrYn) {
if(this.isNull(rtnArrYn)){
rtnArrYn='N';
}
// var regExp = /(^[A-Za-z0-9_\.\-]+)@([A-Za-z0-9\-]+\.[A-Za-z0-9\-]+)/;
var regExp = /^([0-9a-zA-Z_\.\-]([-_.]?[0-9a-zA-Z_\.\-])*)@([0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$)/i;//이메일 정규식
if(regExp.test(email) == false) {
// 이메일 형식이 알파벳+숫자@알파벳+숫자.알파벳+숫자 형식이 아닐경우
if(rtnArrYn == 'Y'){
return email;
}
return false;
}else{
var myArray = regExp.exec(email);
if(rtnArrYn == 'Y'){
return myArray;
}
return true;
}
},
/** * 전화번호 포맷으로 변환 * * @param 데이터 */
formatPhone(phoneNum,fmt,rtnArrYn) {
if(this.isNull(fmt)){
fmt='';
}
if(this.isNull(rtnArrYn)){
fmt='N';
}
if(this.isPhone(phoneNum)) {
var rtnNum;
var regExp =/(02)([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
rtnNum = myArray[1]+fmt + myArray[2]+fmt+myArray[3];
if(rtnArrYn == 'Y'){
return myArray;
}
return rtnNum;
} else {
regExp =/(0[3-9]{1}[0-9]{1})([0-9]{3,4})([0-9]{4})$/;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
rtnNum = myArray[1]+fmt+myArray[2]+fmt+myArray[3];
if(rtnArrYn == 'Y'){
return myArray;
}
return rtnNum;
} else {
return phoneNum;
}
}
} else {
return phoneNum;
}
},
/** * 핸드폰번호 포맷으로 변환 * * @param 데이터 */
formatMobile(phoneNum,fmt,rtnArrYn) {
if(this.isNull(fmt)){
fmt='';
}
if(this.isNull(rtnArrYn)){
fmt='N';
}
if(this.isMobile(phoneNum)) {
var rtnNum;
var regExp =/(01[016789])([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
rtnNum = myArray[1]+fmt+myArray[2]+fmt+myArray[3];
if(rtnArrYn == 'Y'){
return myArray;
}
return rtnNum;
} else {
return phoneNum;
}
} else {
return phoneNum;
}
},
/** * 전화번호 형식 체크 * * @param 데이터 */
isPhone(phoneNum) {
var regExp =/(02)([0-9]{3,4})([0-9]{4})$/;
if(regExp.test(phoneNum)){
return true;
} else {
regExp =/(0[3-9]{1}[0-9]{1})([0-9]{3,4})([0-9]{4})$/;
if(regExp.test(phoneNum)){
return true;
} else {
return false;
}
}
},
/** * 핸드폰번호 형식 체크 * * @param 데이터 */
isMobile(phoneNum) {
var regExp =/(01[016789])([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
return true;
} else {
return false;
}
},
isMobile2(phoneNum) {
var regExp =/(1[016789])([0-9]{3,4})([0-9]{4})$/;
var myArray;
if(regExp.test(phoneNum)){
myArray = regExp.exec(phoneNum);
return true;
} else {
return false;
}
},
isNull(obj){
if(lodash.isNil(obj) || lodash.trim(obj) == ''){
return true;
}
return false;
},
getParent(name){
let p = this.$parent;
while(typeof p !== 'undefined'){
if(p.$options.name == name) {
return p;
}else {
p = p.$parent;
}
}
return false;
},
getJsonObj(str){
return JSON.parse(JSON.stringify(str));
},
}
};
var chkPattern2 = {
data: function () {
return {
}
},
methods: {
selSesStorage(keyLike){
if(this.isNull(keyLike)){
return null;
}
if(sessionStorage.length > 0){
let keyList = [];
for(let i=0;i<sessionStorage.length;i++){
const keyNm = sessionStorage.key(i);
if(keyNm.indexOf(keyLike) > -1){
keyList.push({name : keyNm, value : sessionStorage.getItem(keyNm)});
}
}
if(keyList.length > 0){
return keyList;
}
return null;
}
return null;
},
delSesStorage(keyList){
if(this.isNull(keyList)){
return null;
}
if(keyList.length > 0){
keyList.map((o) => (sessionStorage.removeItem(o.name)));
return true;
}
},
setGridMouseDownActive(){
const ele = document.querySelector(`div.tui-grid-container.tui-grid-show-lside-area`);
if(window.getEventListeners(ele).mousedown){
ele.removeEventListener('mousedown',window.getEventListeners(ele).mousedown[0].listener);
}
},
restrictChars : function($event,regExp,hanYn){
if(this.isNull(hanYn)){
hanYn='N';
}
if(hanYn === 'N' && $event.type === 'keydown'){
if($event.keyCode === 229){
$event.preventDefault();
return false;
}
}
if($event.type === 'keypress'){
//한글 처리 불가
if(regExp.test(String.fromCharCode($event.charCode))) {
return true;
}else{
$event.preventDefault();
return false;
}
}
if(hanYn === 'N' && ( $event.type === 'keyup' || $event.type === 'input' || $event.type === 'change' || $event.type === 'blur')){
$event.target.value = $event.target.value.replace(/[ㄱ-ㅎㅏ-ㅣ가-힣]/g,'');
$event.preventDefault();
return false;
}
return true;
},
setLenth: function (e, len) {
this.cut(e, len);
},
onlyCustom: function (e,strRegExp,hanYn) {
var regExp_g = new RegExp(strRegExp,'g');
this.cut(e);
return this.restrictChars(e,regExp_g,hanYn);
},
onlyCommon: function(strRegExp, e, len, isEventCall, hanYn) {
var regExp_g = new RegExp(strRegExp,'g');
if(isEventCall === 'N'){
if(!this.cut(e, len, isEventCall)){
return false;
}
if(!regExp_g.test(e.value)){
return false;
}
return true;
}
this.cut(e, len);
return this.restrictChars(e,regExp_g,hanYn);
},
onlyNum: function (e, len, isEventCall) {
var strRegExp = '^[0-9]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyEng: function (e, len, isEventCall) {
var strRegExp = '^[A-Za-z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyLowerEng: function (e, len, isEventCall) {
var strRegExp = '^[a-z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyUpperEng: function (e, len, isEventCall) {
var strRegExp = '^[A-Z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyEmail: function (e, len, isEventCall) {
var strRegExp = '^[a-zA-Z0-9_\.\-@._-]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyName: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyTitle: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyText: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9_-]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyPassword: function (e, len, isEventCall) {
var strRegExp = '^[A-Za-z0-9!@#$%^&*]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyId: function (e, len, isEventCall) {
var strRegExp = '^[A-Za-z0-9_\.\-]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyIp: function (e, len, isEventCall) {
var strRegExp = '^[0-9,.*]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
onlyRoleNm_Space: function (e, len, isEventCall) {
var strRegExp = '^[ㄱ-ㅎㅏ-ㅣ가-힣a-zA-Z0-9]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall,'Y');
},
onlyRoleId_UnderBar: function (e, len, isEventCall) {
var strRegExp = '^[a-zA-Z0-9_]*$';
return this.onlyCommon(strRegExp, e, len, isEventCall);
},
cut: function (ele, len, isValidChk) {
let e=ele;
if (typeof ele.target != "undefined") {
e=ele.target;
}
let max = this.isNull(len) ? e.attributes.maxlength.value : len;
let str = e.value;
if (this.bytes(str) > max) {
if(this.isNull(isValidChk)){
e.value = this.cutBytes(str, max);
}
return false;
}
return true;
},
cutBytes: function (str, len) {
while(1 === 1){
if(this.bytes(str) <= len){
return str;
}
str = str.slice(0,-1);
}
},
bytes: function (str) {
var length = ((s,b,i,c) => {
// for(b=i=0;c=s.charCodeAt(i++);b+=c>>11?3:c>>7?2:1); // 한글 3바이트
// for(b=i=0;c=s.charCodeAt(i++);b+=c>>11?2:c>>7?1:1); //한글 2바이트
b=0,i=0;
while(1 === 1){
c = s.charCodeAt(i++);
if (isNaN(c)) {
break;
}
b += c >> 11 ? 2 : c >> 7 ? 1 : 1;
}
return b
})(str);
return length;
},
checkPhone: function(str) {
str = str.replace(/[-\s]+/g, '');
if (str.charAt(0)!="0"){
str = "0"+str;
}
if (str.length<10||str.length>12){return "";}
if (isNaN(str)){return ""; }
if (str.substr(0,2)!="01" && str.substr(0,3)!="070" && str.substr(0,4)!="0505" && str.substr(0,4)!="0503"){return ""; }
return str;
},
}
};
export { utils_mixin, chkPattern2, filter_mixin };

View File

@@ -1,107 +1,273 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">관리자 목록 조회</h3>
<p class="breadcrumb">시스템관리 &gt; 권한 관리</p>
</div>
<div class="info">
<div class="count"> <span>4</span></div>
<div class="button_group">
<button type="button" class="button blue add" onclick="location.href='system_right_add.html';">권한 추가</button>
</div>
</div>
<div class="table">
<table>
<colgroup>
<col width="10%"/>
<col width="20%"/>
<col width="20%"/>
<col width="15%"/>
<col width="20%"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th>NO</th>
<th>코드</th>
<th>권한명</th>
<th>상태</th>
<th>등록일</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey" onclick="location.href='system_right_modify.html';">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>3</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>2</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>1</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'authList',
data() {
return {
};
},
components: {
},
destroyed() {
},
mounted() {
},
methods: {
}
};
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">관리자/유치채널 관리</h3>
<p class="breadcrumb">시스템관리 &gt; 관리자/유치채널 관리</p>
</div>
<form autocomplete="off" class="search_form">
<div class="search_wrap">
<div class="select_box">
<label for="right" class="label">권한</label>
<select name="" id="right" v-model="grid.params.searchType1" @keyup.enter="search">
<option value="">전체</option>
<option v-for="(option, i) in authType" v-bind:value="option.autCd" v-bind:key="i">
{{ option.autNm }}
</option>
</select>
</div>
<div class="select_box">
<label for="right" class="label">상태</label>
<select name="" id="" v-model="grid.params.searchType2" @keyup.enter="search">
<option value="" selected>전체</option>
<option v-for="(option, i) in statType" v-bind:value="option.code" v-bind:key="i">
{{ option.codeNm }}
</option>
</select>
</div>
<div class="input_box id">
<label for="id1" class="label">ID</label>
<input type="text" id="id1" placeholder="검색어 입력" v-model="grid.params.searchText1" @keyup.enter="search"/>
</div>
<div class="input_box">
<label for="name" class="label">이름(대리점명)</label>
<input type="text" id="name" placeholder="검색어 입력" v-model="grid.params.searchText2" @keyup.enter="search"/>
</div>
<button type="button" class="button grey" @click="search">조회</button>
</div>
</form>
<div class="info">
<div class="count"> <span>{{ totalItems }}</span></div>
<div class="button_group">
<button type="button" class="button blue admin add" @click="adminRegPopOpen();">관리자 등록</button>
<button type="button" class="button blue channel add" @click="adminReg2PopOpen();">유치채널 등록</button>
<button type="button" class="button white delete del" @click="deleteRow();">삭제</button>
</div>
</div>
<div class="table">
<custom-grid
ref="table"
:totalItems="'totalItems'"
:url="grid.url"
:pagePerRows="grid.pagePerRows"
:initialRequest="grid.initialRequest"
:pagination="grid.pagination"
:isCheckbox="grid.isCheckbox"
:columns="grid.columns"
:noDataStr="grid.noDataStr"
:addCls="grid.addCls"
:header="grid.headder"
></custom-grid>
</div>
<admin-reg-pop ref="adminRegModal"> </admin-reg-pop>
<!-- <admin-reg2-pop ref="adminReg2Modal"> </admin-reg2-pop> -->
<admin-detail-pop ref="adminDetailModal"> </admin-detail-pop>
</div>
</div>
</template>
<script>
import customGrid from '@/components/CustomGrid';
import AdminRegPop from '../components/AdminRegPop';
//import AdminReg2Pop from '../components/AdminReg2Pop';
import AdminDetailPop from '../components/AdminDetailPop';
import api from '@/service/api.js';
import sysMgtApi from "../service/sysMgtApi.js";
class CustomATagRenderer {
constructor(props) {
this.props = props;
const el = document.createElement('a');
el.href = 'javascript:void(0);';
el.className = 'btn_text';
el.innerText= String(props.colValue)
this.el = el;
}
getElement() {
return this.el;
}
addEvent(selEl) {
selEl.addEventListener("click", () => {
const { callback } = this.props["cgrido" + this.props.colName].options;
callback(this.props);
});
}
}
export default {
name: 'adminList',
data() {
return {
row: {},
authType: [],
statType: [],
cate2Code: "",
totalItems: 0,
// 테이블 리스트 데이터
perPageCnt: 20,
grid: {
url: '/api/v1/bo/sysMgt/adminList',
pagePerRows: 20,
pagination: true,
isCheckbox: true, // true:첫번째 컬럼 앞에 체크박스 생성 / false:체크박스 제거
initialRequest: false,
addCls: 'box_OFvis',
columns: [
{ name: 'no', header: 'No', align: 'center', width: 60},
{ name: 'auth', header: '권한', align: 'center', width: 160 },
{ name: 'name', header: '이름(대리점명)', align: 'center', width: 130, renderer: {
type: CustomATagRenderer
, options: {
callback: this.detailPop,
}
}
},
{ name: 'adminId', header: 'ID', align: 'center', width: 130},
{ name: 'adminStat', header: '상태', align: 'center', width: 130, cls: 'td_line'},
{ name: 'regDt', header: '등록일', align: 'center', width: 130}
],
noDataStr: '검색 결과가 없습니다.',
params: {
searchType1: '',
searchType2: '',
searchText1: '',
searchText2: ''
},
excelHeader: []
}
};
},
components: {
customGrid: customGrid,
// SystemPopup,
AdminRegPop,
//AdminReg2Pop,
AdminDetailPop
},
created(){
this.$store.commit("login/isLogin", true);
this.$store.commit("login/isAuthChk", true);
this.setCodeData();
//let cont = document.querySelector(".wrap");
//cont.classList.add("main_wrap");
},
destroyed() {
},
mounted() {
let page = 1;
// 페이지 정보 및 검색 조건
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
console.log('getCondition : '+getCondition);
// store에 저장된 페이지 정보 및 검색 조건을 불러오기
let isKeep = false;
if (getCondition) {
this.grid.pagePerRows = getCondition.perPage;
this.grid.params = getCondition.params;
page = getCondition.page;
isKeep = true;
}
this.search(isKeep);
},
methods: {
search: function(isKeep) {
console.log('this.perPageCnt'+this.perPageCnt);
//console.log(this.grid.params);
this.$refs.table.search(this.grid.params, isKeep);
this.sendStoreData();
},
detailPop(props) {
// this.getMainSlot().popupView(4);
// this.setDtlPpPrm(props);
this.$refs.adminDetailModal.adminDetailModalOpen(props);
},
ModalOpen: function(target){
//this.$refs.systemModal.ModalOpen(target);
},
adminRegPopOpen: function(){
this.$refs.adminRegModal.ModalOpen(1);
},
adminReg2PopOpen: function(){
this.$refs.adminRegModal.ModalOpen(2);
//this.$refs.adminReg2Modal.adminReg2ModalOpen();//
},
doValidate(){ //로우데이터 삭제하도록 수정
console.log("totalItems >> " + this.totalItems);
if(this.totalItems == 0){
alert('검색 결과가 없습니다.');
return false;
}
var chkList = this.$refs.table.checkedElementDatas();
if(chkList.length == 0){
alert('체크박스에 체크를 해주세요.');
return false;
}
// for(var i = 0; i < chkList.length; i++){
// alert(chkList[i].adminId);
// }
const param = chkList.map((row)=>({adminId:row.adminId}));
this.row.list = param;
console.log(this.row);
return true;
},
sendStoreData: function() {
const getP = this.$refs.table.getPagination();
console.log("==========getP : " + getP);
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params
});
const getCondition = this.$store.getters['searchcondition/getSearchCondition'];
//console.log("getCondition : "+ getCondition.perPage);
},
setCodeData() {
// 상태 옵션 셋팅.
api.commCode({'grpCd' : 'ADM_STTUS_CD'}).then(response => {
this.statType = response.data.data.list;
});
api.commAuth().then(response => {
this.authType = response.data.data.list;
});
},
async deleteRow(){
if(this.doValidate() && window.confirm('삭제 하시겠습니까?')){
try {
let response = await sysMgtApi.deleteAdmin(this.row);
const result = response.data;
if (result != null && result.retCode == "0000") {
alert('삭제 하였습니다.');
// grid.reloadData();
this.$refs.table.reloadData();
return;
}
alert("실패 하였습니다.");
} catch(err) {
alert("실패 하였습니다.");
}
}
},
},
beforeRouteLeave(to, from, next) {
const getP = this.$refs.table.getPagination();
console.log("==========getP : " + getP._currentPage);
this.$store.commit('searchcondition/updateSearchCondition', {
page: getP._currentPage,
perPage: this.perPageCnt,
params: this.grid.params
});
// 라우트 하기전 실행
next();
}
};
</script>

View File

@@ -1,107 +1,107 @@
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">권한 관리</h3>
<p class="breadcrumb">시스템관리 &gt; 권한 관리</p>
</div>
<div class="info">
<div class="count"> <span>4</span></div>
<div class="button_group">
<button type="button" class="button blue add" onclick="location.href='system_right_add.html';">권한 추가</button>
</div>
</div>
<div class="table">
<table>
<colgroup>
<col width="10%"/>
<col width="20%"/>
<col width="20%"/>
<col width="15%"/>
<col width="20%"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th>NO</th>
<th>코드</th>
<th>권한명</th>
<th>상태</th>
<th>등록일</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey" onclick="location.href='system_right_modify.html';">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>3</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>2</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>1</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'authList',
data() {
return {
};
},
components: {
},
destroyed() {
},
mounted() {
},
methods: {
}
};
<template>
<div class="contents">
<div class="contents_wrap">
<div class="top_wrap">
<h3 class="title">권한 관리</h3>
<p class="breadcrumb">시스템관리 &gt; 권한 관리</p>
</div>
<div class="info">
<div class="count"> <span>4</span></div>
<div class="button_group">
<button type="button" class="button blue add" onclick="location.href='system_right_add.html';">권한 추가</button>
</div>
</div>
<div class="table">
<table>
<colgroup>
<col width="10%"/>
<col width="20%"/>
<col width="20%"/>
<col width="15%"/>
<col width="20%"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th>NO</th>
<th>코드</th>
<th>권한명</th>
<th>상태</th>
<th>등록일</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey" onclick="location.href='system_right_modify.html';">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>3</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>2</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
<tr>
<td>1</td>
<td>Admin_01</td>
<td>슈퍼관리자</td>
<td>사용</td>
<td>2022-03-10</td>
<td class="two_btn_group">
<button type="button" class="button grey">수정</button>
<button type="button" class="button white delete">삭제</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'authList',
data() {
return {
};
},
components: {
},
destroyed() {
},
mounted() {
},
methods: {
}
};
</script>

View File

@@ -1,97 +1,97 @@
import Vue from 'vue';
import Router from 'vue-router';
import searchcondition from './store'
import tokenSvc from '@/common/token-service';
import HubwebLayout from './views/HubwebLayout.vue';
import loginRoutes from './modules/login/router';
import custRoutes from './modules/custMgt/router';
import authRoutes from './modules/sysMgt/router';
import custList from './modules/custMgt/views/CustList';
import channelRoutes from './modules/attractMgt/router';
import rejectRoutes from './modules/servMgt/router';
import clacRoutes from './modules/calculate/router';
import templtRoutes from './modules/channelMgt/router';
import profileRoutes from './modules/sendNumMgt/router';
import mntrngRoutes from './modules/mntrng/router';
import riskmgtRoutes from './modules/riskMgt/router';
import monthRoutes from './modules/stats/router';
// import channelList from './modules/attractMgt/views/ChannelList';
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
component: HubwebLayout,
children: [
{
path: '',
component: custList
},
// {
// path: '/attractMgt/views',
// component: channelList
// },
{
path: '/view/error/404',
component: () => import('./views/ErrorPage404.vue'),
meta: { public: true }
},
{
path: '/view/error/500',
component: () => import('./views/ErrorPage500.vue'),
meta: { public: true }
},
...loginRoutes,
...custRoutes,
...authRoutes,
...channelRoutes,
...rejectRoutes,
...clacRoutes,
...templtRoutes,
...profileRoutes,
...mntrngRoutes,
...riskmgtRoutes,
...monthRoutes,
]
},
{path: '*', redirect: '/view/error/404'}
]
});
router.beforeEach((to, from, next) => {
const isPublic = to.matched.some(record => record.meta.public);
const loggedIn = !!tokenSvc.getToken();
if (!isPublic && !loggedIn) {
return next('/login');
}
to.matched.some(record => {
if (record.meta.usingSearchCondition) {
const shareList = record.meta.shareList;
if (from.name && shareList && shareList.includes(from.name)) {
// shareList에 포함되어 있는 라우터에서 온 경우 검색 조건을 유지한다.
// console.log("패밀리");
} else {
// 그 외의 경우 검색 조건 초기화
searchcondition.commit("searchcondition/updateSearchCondition", null);
// console.log("낫패밀리");
}
}
next();
});
});
export default router;
import Vue from 'vue';
import Router from 'vue-router';
import searchcondition from './store'
import tokenSvc from '@/common/token-service';
import HubwebLayout from './views/HubwebLayout.vue';
import loginRoutes from './modules/login/router';
import custRoutes from './modules/custMgt/router';
import authRoutes from './modules/sysMgt/router';
import custList from './modules/custMgt/views/CustList';
import channelRoutes from './modules/attractMgt/router';
import rejectRoutes from './modules/servMgt/router';
import clacRoutes from './modules/calculate/router';
import templtRoutes from './modules/channelMgt/router';
import profileRoutes from './modules/sendNumMgt/router';
import mntrngRoutes from './modules/mntrng/router';
import riskmgtRoutes from './modules/riskMgt/router';
import monthRoutes from './modules/stats/router';
// import channelList from './modules/attractMgt/views/ChannelList';
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
component: HubwebLayout,
children: [
{
path: '',
component: custList
},
// {
// path: '/attractMgt/views',
// component: channelList
// },
{
path: '/view/error/404',
component: () => import('./views/ErrorPage404.vue'),
meta: { public: true }
},
{
path: '/view/error/500',
component: () => import('./views/ErrorPage500.vue'),
meta: { public: true }
},
...loginRoutes,
...custRoutes,
...authRoutes,
...channelRoutes,
...rejectRoutes,
...clacRoutes,
...templtRoutes,
...profileRoutes,
...mntrngRoutes,
...riskmgtRoutes,
...monthRoutes,
]
},
{path: '*', redirect: '/view/error/404'}
]
});
router.beforeEach((to, from, next) => {
const isPublic = to.matched.some(record => record.meta.public);
const loggedIn = !!tokenSvc.getToken();
if (!isPublic && !loggedIn) {
return next('/login');
}
to.matched.some(record => {
if (record.meta.usingSearchCondition) {
const shareList = record.meta.shareList;
if (from.name && shareList && shareList.includes(from.name)) {
// shareList에 포함되어 있는 라우터에서 온 경우 검색 조건을 유지한다.
// console.log("패밀리");
} else {
// 그 외의 경우 검색 조건 초기화
searchcondition.commit("searchcondition/updateSearchCondition", null);
// console.log("낫패밀리");
}
}
next();
});
});
export default router;

View File

@@ -1,46 +1,56 @@
import httpClient from '@/common/http-client';
/* ckr - old
const menus = () => {
return httpClient.get('/api/view/menus');
};
*/
// new
const menus = () => {
return httpClient.post('/api/v1/bo/comm/getMenu',{ withCredentials: false });
};
const generateStr = (length) => {
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var result = "";
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
/**
* httpClient.get(url, { params, responseType: "blob" }).then(response => { commonApiService.downloadBlob(response); })
*/
const downloadBlob = (response) => {
let blob = new Blob([response.data], { type: "application/vnd.ms-excel;charset=UTF-8" });
let filename = response.headers["content-disposition"].split(";")
.filter(function(ele) { return ele.indexOf("filename") > -1 })
.map(function(ele) { return ele.replace(/"/g, '').split("=")[1] });
filename = decodeURI(filename);
if (typeof window.navigator.msSaveBlob !== "undefined") {
// IE
window.navigator.msSaveBlob(blob, filename);
} else {
let link = document.createElement("a")
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.click();
}
}
export default {
menus,
generateStr,
downloadBlob
import httpClient from '@/common/http-client';
/* ckr - old
const menus = () => {
return httpClient.get('/api/view/menus');
};
*/
// new
const menus = () => {
return httpClient.post('/api/v1/bo/comm/getMenu', { withCredentials: false });
};
const commCode = (params) => {
return httpClient.post('/api/v1/bo/comm/getCode', params, { withCredentials: false });
};
const commAuth = () => {
return httpClient.post('/api/v1/bo/comm/getAuth', { withCredentials: false });
};
const generateStr = (length) => {
const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var result = "";
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
/**
* httpClient.get(url, { params, responseType: "blob" }).then(response => { commonApiService.downloadBlob(response); })
*/
const downloadBlob = (response) => {
let blob = new Blob([response.data], { type: "application/vnd.ms-excel;charset=UTF-8" });
let filename = response.headers["content-disposition"].split(";")
.filter(function(ele) { return ele.indexOf("filename") > -1 })
.map(function(ele) { return ele.replace(/"/g, '').split("=")[1] });
filename = decodeURI(filename);
if (typeof window.navigator.msSaveBlob !== "undefined") {
// IE
window.navigator.msSaveBlob(blob, filename);
} else {
let link = document.createElement("a")
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.click();
}
}
export default {
menus,
generateStr,
downloadBlob,
commCode,
commAuth
};

View File

@@ -1,31 +1,31 @@
import httpClient from '@/common/http-client';
const commonUpload = file => {
let formData = new FormData();
formData.append('sourceFile', file);
return httpClient.post('/api/file/common/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
};
const commonMultiUpload = files => {
let formData = new FormData();
for (let x = 0; x < files.length; x++) {
formData.append('sourceFiles', files[x]);
}
return httpClient.post('/api/file/common/upload/multi', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
};
export default {
commonUpload,
commonMultiUpload
};
import httpClient from '@/common/http-client';
const commonUpload = file => {
let formData = new FormData();
formData.append('sourceFile', file);
return httpClient.post('/api/file/common/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
};
const commonMultiUpload = files => {
let formData = new FormData();
for (let x = 0; x < files.length; x++) {
formData.append('sourceFiles', files[x]);
}
return httpClient.post('/api/file/common/upload/multi', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
};
export default {
commonUpload,
commonMultiUpload
};

View File

@@ -1,13 +1,13 @@
import Vue from 'vue'
import Vuex from 'vuex'
import searchcondition from './store/search-condition'
import login from './modules/login/store/index'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
searchcondition,
login
}
})
import Vue from 'vue'
import Vuex from 'vuex'
import searchcondition from './store/search-condition'
import login from './modules/login/store/index'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
searchcondition,
login
}
})

View File

@@ -1,24 +1,24 @@
const state = {
searchCondition: null
}
const getters = {
getSearchCondition: state => state.searchCondition,
}
const mutations = {
updateSearchCondition: (state, data) => {
state.searchCondition = data;
}
}
const actions = {
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
const state = {
searchCondition: null
}
const getters = {
getSearchCondition: state => state.searchCondition,
}
const mutations = {
updateSearchCondition: (state, data) => {
state.searchCondition = data;
}
}
const actions = {
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,37 @@
<template>
<article id="content" class="content error_page">
<div class="error_wrap center">
<div class="title_area rcs_icon icon_error404">
<h2 class="h2_title">죄송합니다.<br>요청하신 페이지를 찾을 없습니다. (404 Error)</h2><span class="h2_desc mar_t20">존재하지 않는 주소를 입력하셨거나 기술적인 문제로 일시적으로 접속되지 않았습니다.<br>잠시 다시 이용 부탁드리며 이용에 불편을 드려 사과드립니다.</span>
</div>
<div class="btn_wrap center mar_t60"><a href="javascript:void(0);" class="btn big cd_black" @click="backGo"><span>이전</span></a><a href="/" class="btn big point"><span>메인</span></a></div>
</div>
</article>
</template>
<script>
export default {
data: function() {
return {
};
},
created() {
this.$store.commit("login/isErrorPage", true);
},
mounted() {
},
destroyed() {
this.$store.commit("login/isErrorPage", false);
},
methods: {
backGo() {
this.$router.go(-1);
}
}
};
</script>
<template>
<article id="content" class="content error_page">
<div class="error_wrap center">
<div class="title_area rcs_icon icon_error404">
<h2 class="h2_title">죄송합니다.<br>요청하신 페이지를 찾을 없습니다. (404 Error)</h2><span class="h2_desc mar_t20">존재하지 않는 주소를 입력하셨거나 기술적인 문제로 일시적으로 접속되지 않았습니다.<br>잠시 다시 이용 부탁드리며 이용에 불편을 드려 사과드립니다.</span>
</div>
<div class="btn_wrap center mar_t60"><a href="javascript:void(0);" class="btn big cd_black" @click="backGo"><span>이전</span></a><a href="/" class="btn big point"><span>메인</span></a></div>
</div>
</article>
</template>
<script>
export default {
data: function() {
return {
};
},
created() {
this.$store.commit("login/isErrorPage", true);
},
mounted() {
},
destroyed() {
this.$store.commit("login/isErrorPage", false);
},
methods: {
backGo() {
this.$router.go(-1);
}
}
};
</script>

View File

@@ -1,37 +1,37 @@
<template>
<article id="content" class="content error_page">
<div class="error_wrap center">
<div class="title_area rcs_icon icon_error500">
<h2 class="h2_title">죄송합니다.<br>서비스가 일시적으로 중단되었습니다. (500 Error)</h2><span class="h2_desc mar_t20">일시적으로 페이지 접근이 불가능합니다.<br>잠시 다시 이용 부탁드리며 이용에 불편을 드려 사과드립니다.</span>
</div>
<div class="btn_wrap center mar_t60"><a href="javascript:void(0);" class="btn big cd_black" @click="backGo"><span>이전</span></a><a href="/" class="btn big point"><span>메인</span></a></div>
</div>
</article>
</template>
<script>
export default {
data: function() {
return {
};
},
created() {
this.$store.commit("login/isErrorPage", true);
},
mounted() {
},
destroyed() {
this.$store.commit("login/isErrorPage", false);
},
methods: {
backGo() {
this.$router.go(-1);
}
}
};
<template>
<article id="content" class="content error_page">
<div class="error_wrap center">
<div class="title_area rcs_icon icon_error500">
<h2 class="h2_title">죄송합니다.<br>서비스가 일시적으로 중단되었습니다. (500 Error)</h2><span class="h2_desc mar_t20">일시적으로 페이지 접근이 불가능합니다.<br>잠시 다시 이용 부탁드리며 이용에 불편을 드려 사과드립니다.</span>
</div>
<div class="btn_wrap center mar_t60"><a href="javascript:void(0);" class="btn big cd_black" @click="backGo"><span>이전</span></a><a href="/" class="btn big point"><span>메인</span></a></div>
</div>
</article>
</template>
<script>
export default {
data: function() {
return {
};
},
created() {
this.$store.commit("login/isErrorPage", true);
},
mounted() {
},
destroyed() {
this.$store.commit("login/isErrorPage", false);
},
methods: {
backGo() {
this.$router.go(-1);
}
}
};
</script>

View File

@@ -1,78 +1,79 @@
<template>
<body>
<div class="wrap" v-bind:class="{'main_wrap': (isLogin && isAuthChk), 'login-wrap': (!isLogin && !isAuthChk), 'bg-wrap': (isLogin && !isAuthChk) }" >
<hub-web-header v-if="isAuthChk == true"></hub-web-header>
<nav-bar v-if="isAuthChk == true"></nav-bar>
<router-view :key="$route.fullPath"></router-view>
<hub-web-footer v-if="isAuthChk == false"></hub-web-footer>
</div>
</body>
</template>
<script>
import NavBar from "../components/NavBar.vue";
//import vuejsDatepicker from "../components/vuejs-datepicker";
import HubWebHeader from "../components/HubWebHeader.vue";
import HubWebFooter from "../components/HubWebFooter.vue";
import "../common/ko.js";
import "../assets/css/layout.css";
import "../assets/css/contents.css";
import "../assets/css/common.css";
import "../assets/css/style.css";
import { mapGetters } from 'vuex';
export default {
name: "hubwebLayout",
components: {
NavBar,
//vuejsDatepicker,
HubWebHeader,
HubWebFooter,
},
data(){
return{
isLogin: false,
isErrPage: false,
isAuthChk: false,
}
},
created() {
this.getLogin;
this.getAuthChk;
},
mounted() {
}
,computed: {
...mapGetters({
getLogin: 'login/isLogin',
getErrorPage: 'login/isErrorPage',
getAuthChk: 'login/isAuthChk',
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
getErrorPage(data) {
if (data != null && data != '' && data == true) {
this.isErrPage = true;
} else {
this.isErrPage = false;
}
},
getAuthChk(data) {
if (data != null && data != '' && data == true) {
this.isAuthChk = true;
} else {
this.isAuthChk = false;
}
},
}
};
<template>
<body>
<div class="wrap" v-bind:class="{'main_wrap': (isLogin && isAuthChk), 'login-wrap': (!isLogin && !isAuthChk), 'bg-wrap': (isLogin && !isAuthChk) }" >
<hub-web-header v-if="isAuthChk == true"></hub-web-header>
<nav-bar v-if="isAuthChk == true"></nav-bar>
<router-view :key="$route.fullPath"></router-view>
<hub-web-footer v-if="isAuthChk == false"></hub-web-footer>
</div>
</body>
</template>
<script>
import NavBar from "../components/NavBar.vue";
//import vuejsDatepicker from "../components/vuejs-datepicker";
import HubWebHeader from "../components/HubWebHeader.vue";
import HubWebFooter from "../components/HubWebFooter.vue";
import "../common/ko.js";
import "../assets/css/layout.css";
import "../assets/css/contents.css";
import "../assets/css/common.css";
import "../assets/css/style.css";
import { mapGetters } from 'vuex';
export default {
name: "hubwebLayout",
components: {
NavBar,
//vuejsDatepicker,
HubWebHeader,
HubWebFooter,
},
data(){
return{
isLogin: false,
isErrPage: false,
isAuthChk: false,
}
},
created() {
this.getLogin;
this.getAuthChk;
},
mounted() {
}
,computed: {
...mapGetters({
getLogin: 'login/isLogin',
getErrorPage: 'login/isErrorPage',
getAuthChk: 'login/isAuthChk',
}),
},
watch: {
getLogin(data) {
if (data != null && data != '' && data == true) {
this.isLogin = true;
} else {
this.isLogin = false;
}
},
getErrorPage(data) {
if (data != null && data != '' && data == true) {
this.isErrPage = true;
} else {
this.isErrPage = false;
}
},
getAuthChk(data) {
if (data != null && data != '' && data == true) {
this.isAuthChk = true;
} else {
this.isAuthChk = false;
}
},
}
};
</script>