mirror of
http://git.mhez-qa.uplus.co.kr/hubez/hubez-admin.git
synced 2025-12-07 05:12:34 +09:00
- 시스템관리 > 관리자목록조회, 관리자등록, 관리자수정, 관리자삭제, 관리자상세조회
This commit is contained in:
@@ -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>
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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
Reference in New Issue
Block a user