141 lines
4.5 KiB
Vue
141 lines
4.5 KiB
Vue
<template>
|
|
<div class="col-md-6 col-lg-4 col-xl-4 order-0 mb-6">
|
|
<div class="card h-100">
|
|
<!-- 더보기 버튼 -->
|
|
<div class="d-flex ">
|
|
<router-link
|
|
to="/wordDict"
|
|
class="btn btn-primary mr-1 pe-1 ps-1 ms-auto my-auto h-50"
|
|
>
|
|
more
|
|
</router-link>
|
|
</div>
|
|
<div class="card-header d-flex justify-content-between">
|
|
<div class="card-title mb-0">
|
|
<h5 class="mb-1 me-2">용어집</h5>
|
|
</div>
|
|
</div>
|
|
<div class="card-body" v-if="wordList.length > 0">
|
|
<ul class="p-0 m-0" v-for="item in wordList" :key="item.WRDDICSEQ">
|
|
<li class="d-flex align-items-center mb-1">
|
|
<!-- 프로필 이미지 -->
|
|
<div class="avatar flex-shrink-0 me-2 d-flex align-items-center">
|
|
<img
|
|
class="rounded-circle user-avatar object-fit-contain"
|
|
:src="getProfileImage(item.lastEditor.profileImage)"
|
|
alt="최종 작성자"
|
|
:style="{ borderColor: item.lastEditor.color }"
|
|
@error="setDefaultImage"
|
|
/>
|
|
</div>
|
|
|
|
<!-- 텍스트 영역 -->
|
|
<div class="timeline-event ps-1 flex-grow-1" style="cursor: pointer;" @click="goWordList(item.WRDDICCAT,item.WRDDICTTL)">
|
|
<div class="timeline-header">
|
|
<small class="text-primary text-uppercase">{{ item.category }}</small>
|
|
</div>
|
|
<h6 class="my-50 d-flex align-items-center">
|
|
{{ truncateTitle(item.WRDDICTTL) }}
|
|
</h6>
|
|
<div class="text-muted small">{{$common.dateFormatter(item.lastEditor.updatedAt)}}</div>
|
|
</div>
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
<div class="card-body" v-else >
|
|
등록된 용어가 없습니다.
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import axios from '@api';
|
|
import { getCurrentInstance, onMounted, ref } from 'vue';
|
|
import { useRouter } from 'vue-router';
|
|
import commonApi from '@/common/commonApi';
|
|
|
|
const { appContext } = getCurrentInstance();
|
|
const $common = appContext.config.globalProperties.$common;
|
|
const router = useRouter();
|
|
|
|
onMounted(() => {
|
|
getwordList();
|
|
});
|
|
|
|
// 프로필 이미지
|
|
const baseUrl = axios.defaults.baseURL.replace(/api\/$/, '');
|
|
const defaultProfile = "/img/icons/icon.png";
|
|
const getProfileImage = (profilePath) => {
|
|
return profilePath && profilePath.trim() ? `${baseUrl}upload/img/profile/${profilePath}` : defaultProfile;
|
|
};
|
|
const setDefaultImage = (event) => {
|
|
event.target.src = defaultProfile;
|
|
};
|
|
const wordList = ref([]);
|
|
//용어 목록
|
|
const getwordList = (searchKeyword='', indexKeyword='', category='') => {
|
|
axios.get('worddict/getWordList',{
|
|
params: {
|
|
searchKeyword : searchKeyword,
|
|
indexKeyword :indexKeyword,
|
|
category : category,
|
|
pageNum:6
|
|
}
|
|
})
|
|
.then(res => {
|
|
wordList.value = res.data.data.data;
|
|
});
|
|
};
|
|
//초성 /알파벳 변환
|
|
const getFirstCharacter = (char) => {
|
|
const CHOSUNG_LIST = [
|
|
'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ',
|
|
'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'
|
|
];
|
|
|
|
if (!char || char.length === 0) return '';
|
|
|
|
const code = char.charCodeAt(0);
|
|
|
|
// 한글 범위 (가~힣) → 초성 변환
|
|
if (code >= 0xAC00 && code <= 0xD7A3) {
|
|
const index = Math.floor((code - 0xAC00) / (21 * 28));
|
|
return CHOSUNG_LIST[index];
|
|
}
|
|
|
|
// 영어 소문자 → 대문자로 변환
|
|
if (char.match(/[a-zA-Z]/)) {
|
|
return char.toLowerCase();
|
|
}
|
|
|
|
// 기타 문자 (숫자, 특수문자) 그대로 반환
|
|
return char;
|
|
};
|
|
//용어집 이동
|
|
const goWordList = (category, indexKeyword) => {
|
|
const firstChar = getFirstCharacter(indexKeyword[0]); // 첫 글자 변환
|
|
router.push({
|
|
path: '/wordDict',
|
|
query: {
|
|
indexKeyword: firstChar,
|
|
category: category,
|
|
}
|
|
});
|
|
};
|
|
// 제목이 14글자 넘어가면 ... 처리하는 함수
|
|
const truncateTitle = title => {
|
|
return title.length > 25 ? title.slice(0, 25) + '...' : title;
|
|
};
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
.user-avatar {
|
|
border: 3px solid;
|
|
padding: 0.1px;
|
|
}
|
|
</style>
|