File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
<template>
<header :class="['relative', className]" :style="{ background: isHovered ? 'black' : '' }">
<div class="relative content">
<div class="w1280 relative ">
<div class="tnb-zone flex-column justify-center align-end">
<div class="flex align-center">
<div class="user-info" v-if="mbrNm">
<div class="flex align-center">
<div class="flex align-center">
<p class="pd10" aria-label="user info"><svg-icon type="mdi" :width="17" :hight="17"
:path="userPath" role="img" aria-hidden="true"></svg-icon><span> {{
mbrNm }}</span><span v-if="authrtNm">[{{ authrtNm }}]</span>
님
</p>
<p class="pd10 pl5 relative user-alarm cursor" aria-label="alarm" id="alarm"
@click.stop="modalshow">
<svg-icon type="mdi" :width="20" :height="20" :path="bellPath" :color="'#fff'"
role="img" aria-labelledby="alarm"></svg-icon>
<span class="alarm-number notranslate">{{ alarmList.length }}</span>
</p>
</div>
<button class="icon-btn pd10" title="로그아웃" @click="fnlogOut">로그아웃</button>
</div>
</div>
<div class="user-info" v-else>
<div class="flex align-center">
<router-link to="/login.page" class="login pd10 relative">로그인</router-link>
<router-link to="/cmmn/join.page" class="join pd10">회원가입</router-link>
</div>
</div>
<div class="translation-buttons">
<button class="icon-btn white flex align-center notranslate"
aria-label="languageChange" title="다국어" id="languageChange" @click="toggleLanguage"><svg-icon type="mdi"
:width="18" :height="18" :path="worldPath" role="img"
aria-labelledby="languageChange"></svg-icon> <span>{{ language
}}</span></button>
</div>
</div>
</div>
</div>
<div class="w1280">
<div class="flex justify-between align-end content header-sort">
<div :class="{'logo pd10 pl0':true, 'en-logo': language === 'KO'}" >
<a href="/aidt/main.page"
:class="{ 'white': true, 'small-logo': language === 'KO', 'page-sub-title': language === 'EN' }">
<img src="../../resources/img/logo_simbol.png" alt="AI 디지털교과서 통합지원센터 홈 바로가기" />
AI 디지털교과서 통합지원센터
</a>
</div>
<UserMenu v-if="!isMobile" @hover="menuHover" />
<div class="flex align-center" v-else>
<!-- 모바일용 서치 버튼 -->
<button class="icon-btn white pd0 pt10 pb10" title="통합검색" aria-label="searchButton" id="searchButton"
@click="searchShow"><svg-icon type="mdi" :path="searchPath" role="img"
aria-labelledby="searchButton"></svg-icon></button>
<MobileMenu />
</div>
<!-- pc용 서치 버튼 -->
<button v-if="!isMobile" class="icon-btn white pd0 pt10 pb10" title="통합검색" aria-label="searchButton" id="searchButton"
@click="searchShow"><svg-icon type="mdi" :path="searchPath" role="img"
aria-labelledby="searchButton"></svg-icon></button>
</div>
</div>
</div>
<!-- 알람모달 -->
<div class="alarm-modal pd15 border" v-show="alarmModal" v-click-outside="closeModal" role="dialog"
aria-modal="true">
<div class="flex justify-end">
<button class="icon-btn" title="닫기" @click="closeModal"><svg-icon type="mdi" :path="closePath" role="img"
aria-labelledby="modal close"></svg-icon></button>
</div>
<div class="border-b pb10">
<div class="flex justify-between align-center">
<p>알람 <span>{{ alarmList.length }}</span>건</p>
<button class="icon-btn small-text" title="전체읽기" @click="readAll()">전체읽기</button>
</div>
</div>
<ul class="pt10 pb10 overflow-y" style="height:calc(100% - 27px)" v-if="alarmList.length > 0">
<li class="alarm-item pd10 mb5" v-for="(itm, indx) in alarmList" :key="indx">
<div @click="readEvent(itm)" aria-label="alarm icon">
<div class="flex justify-start align-start">
<div class="pd5 alarm-itmcon">
<svg-icon type="mdi" :width="20" :height="20" :path="bellPath" role="img"
aria-labelledby="alarm icon"></svg-icon><span>알람</span>
</div>
<div class="ml10">
<p>{{ itm.evt_cn }}</p>
<p class="small-text">{{ $filters.dateTime(itm.dsptch_dt) }}</p>
</div>
</div>
</div>
</li>
</ul>
<ul class="pt10 pb10" v-else style="height:calc(100% - 27px)">
<div class="flex flex-column justify-center align-center content">
알림 내역이 없습니다.
</div>
</ul>
</div>
<!-- 검색 input -->
<div v-show="openSearch" class="search-wrap">
<div class="w1280">
<div class="pd50 pl100 pr100">
<div class="relative">
<label for="totalsearch" class="visually-hidden">검색어</label>
<input type="text" id="totalsearch" class="full-input pl20 white" placeholder="검색어를 입력해주세요." v-model="searchText"
@keyup.enter="searchPage" />
<button class="icon-btn white pd0 search-btn" title="검색" aria-label="searchButton" id="searchButton" @click="searchPage"><svg-icon type="mdi"
:path="searchPath" role="img" aria-labelledby="searchButton"></svg-icon></button>
</div>
</div>
</div>
</div>
</header>
</template>
<script>
import store from "../../views/pages/AppStore";
import UserMenu from './UserMenu.vue';
import MobileMenu from './MoblieMenu.vue'
import { useStore, mapActions } from "vuex";
import { mdiMagnify, mdiBell, mdiClose, mdiAccount, mdiWeb } from '@mdi/js';
import { color } from "@amcharts/amcharts5";
// api
import { findAllEvent, readEvent, readAllEvent } from "../../resources/api/eventAlarm";
import VueCookies from "vue-cookies";
export default {
props: {
className: {
type: String,
default: ''
}
},
components: {
'UserMenu': UserMenu,
'MobileMenu': MobileMenu
},
data() {
return {
isMobile: false,
mbrNm: store.state.mbrNm,
authrtNm: store.state.authrtNm,
searchPath: mdiMagnify,
store: useStore(),
bellPath: mdiBell,
closePath: mdiClose,
alarmModal: false,
userPath: mdiAccount,
worldPath: mdiWeb,
language: 'EN',
alarmList: [],
timer: {},
openSearch: false,
languageFlag: false,
isHovered: false,
searchText: null,
google : {},
}
},
methods: {
// 메뉴 mouseover 시 헤더 색상 변경
menuHover(isHovered) {
this.isHovered = isHovered;
},
...mapActions(["logout"]),
async fnlogOut() {
if (!confirm(this.$getCmmnMessage("cnf001"))) return;
await this.logout();
store.commit("setStoreReset");
window.location.href = '/';
//this.$router.push({path: '/' });
// this.$router.push({
// path: "/",
// });
},
modalshow() {
this.alarmModal = !this.alarmModal;
},
closeModal() {
this.alarmModal = false;
},
// 번역 토글 버튼
async toggleLanguage() {
this.$setLoading(true);
const gtcombo = document.querySelector('.goog-te-combo');
if (gtcombo) {
// 현재 선택된 언어를 가져옵니다.
const currentLanguage = gtcombo.value;
// 현재 언어가 'en'이면 'ko'로, 'ko'이면 'en'으로 변경합니다.
const newLanguage = currentLanguage === 'en' ? 'ko' : 'en';
// 새로운 언어를 설정합니다.
gtcombo.value = newLanguage;
if (currentLanguage == 'en') {
this.languageFlag = true;
}
this.language = newLanguage === 'ko' ? 'EN' : 'KO';
// 언어 변경 이벤트를 발생시킵니다.
gtcombo.dispatchEvent(new Event('change'));
} else {
alert('Error: Could not find Google translate Combolist.');
}
this.$setLoading(false);
},
// 번역 스크립트
loadGoogleTranslate() {
const vm = this;
if(this.$cookies.get('googtrans') != null){
this.$cookies.set('googtrans','ko/ko')
}
this.google = new google.translate.TranslateElement({ pageLanguage: 'ko', autoDisplay: false, includedLanguages : 'ko,en' }, 'google_translate_element');
document.querySelector('.goog-te-combo').addEventListener('change',function(event) {
//한번더 번역
if (vm.languageFlag == true) {
vm.languageFlag = false;
document.querySelector('.goog-te-combo').value = 'ko'
document.querySelector('.goog-te-combo').dispatchEvent(new Event('change'));
}
});
},
checkMobile() {
this.isMobile = window.innerWidth <= 1199;
},
goUrl: function (url) {
// 현재 페이지의 URL을 가져옵니다. location.href에서 도메인과 프로토콜을 제외한 path만 비교하기 위해 window.location.pathname을 사용합니다.
var currentUrl = window.location.pathname;
// URL 객체를 생성하여 비교를 용이하게 합니다. 이 방법은 절대 경로와 상대 경로 모두에 대응할 수 있습니다.
var incomingUrl = new URL(url, window.location.origin).pathname;
// 제공된 URL이 현재 페이지와 동일한 경우 페이지를 새로 고침합니다.
if (currentUrl === incomingUrl) {
window.location.reload();
} else {
// 다른 경우, 제공된 URL로 이동합니다.
window.location.href = url;
}
},
// 알람정보 확인
async alarmCheck() {
let vm = this;
if (store.state.authorization != null) {
// 실행
try {
const response = await findAllEvent();
vm.alarmList = response.data.data;
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
// alert(error.response.data.message);
} else {
// alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
}
}
},
// 알람 읽음
async readEvent(item) {
let vm = this;
this.alarmModal = false;
// 실행
try {
const response = await readEvent(item);
vm.alarmList = response.data.data;
vm.goUrl(item.url);
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
Logger.logging(error.response.data.message);
// alert(error.response.data.message);
} else {
//alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
}
}
},
// 전체 알람 읽음
async readAll() {
let vm = this;
// 실행
try {
const response = await readAllEvent();
vm.alarmList = response.data.data;
} catch (error) {
const errorData = error.response.data;
if (errorData.message != null && errorData.message != "") {
Logger.logging(error.response.data.message);
} else {
Logger.logging(error.response.data.message);
// alert("에러가 발생했습니다.\n관리자에게 문의해주세요.");
alert(vm.$getCmmnMessage('err005'));
}
}
},
searchShow() {
this.openSearch = !this.openSearch
},
searchPage: function () {
const searchText = this.searchText;
this.searchText = null;
this.openSearch = false;
this.$router.push({ name: 'search', query: { 'searchText': searchText } });
},
},
watch: {
'alarmModal': function (newV, oldV) {
}
},
computed: {
},
mounted() {
let vm = this;
setTimeout(function () {
vm.alarmCheck();
}, 1000);
this.timer = setInterval(this.alarmCheck, 10000);
this.checkMobile();
window.addEventListener('resize', this.checkMobile);
this.loadGoogleTranslate();
},
beforeUnmount() {
clearInterval(this.timer);
window.removeEventListener('resize', this.checkMobile);
this.google = null;
}
}
</script>