Commit cf09a778 authored by shj's avatar shj

[ADD] nuxt-i18n 추가, 인덱스 로드&관리 로컬라이제이션 적용

parent 9d294f2b
......@@ -27,15 +27,14 @@ public class GuideIndexController {
@ApiOperation(value="가이드 인덱스 전체 조회")
@GetMapping("/all")
public ResponseEntity<?> getAll()throws Exception{
return new ResponseEntity<>(service.getAll(), HttpStatus.OK);
public ResponseEntity<?> getAll(@RequestParam(value = "locale", required = false) String locale)throws Exception{
return new ResponseEntity<>(service.getAll(locale), HttpStatus.OK);
}
@ApiOperation(value="가이드 인덱스 추가")
@PostMapping
public ResponseEntity<?> create(@RequestBody GuideIndex index) throws Exception{
return new ResponseEntity<>(service.create(index), HttpStatus.CREATED);
}
@PutMapping
......
......@@ -11,9 +11,10 @@ import java.util.List;
public interface GuideIndexRepository extends CrudRepository<GuideIndex, String> {
List<GuideIndex> findAll();
List<GuideIndex> findAllByOrderByOrder();
List<GuideIndex> findAllByDepthOrderByOrder(Integer depth);
List<GuideIndex> findAllByPathContainingAndDepth(String path, Integer depth);
List<GuideIndex> findAllByPathContainingAndDepthOrderByOrderDesc(String path, Integer depth);
GuideIndex findByPath(String path);
GuideIndex findByPathContainingAndDepthAndOrder(String path, Integer depth, Integer order);
List<GuideIndex> findAllByLocaleOrderByOrder(String locale);
List<GuideIndex> findAllByDepthAndLocaleOrderByOrder(Integer depth, String locale);
List<GuideIndex> findAllByPathContainingAndDepthAndLocale(String path, Integer depth, String locale);
List<GuideIndex> findAllByPathContainingAndDepthAndLocaleOrderByOrderDesc(String path, Integer depth, String locale);
GuideIndex findByPathAndLocale(String path, String locale);
GuideIndex findByPathContainingAndDepthAndOrderAndLocale(String path, Integer depth, Integer order, String locale);
}
......@@ -41,12 +41,12 @@ public class GuideIndexService {
// order == 0 인 경우 부모 인덱스 반환
if(targetIndex.getOrder() == 0){
return repository.findByPath(parentPath);
return repository.findByPathAndLocale(parentPath, targetIndex.getLocale());
}
// 이전 형제의 자식이 없을 경우 해당 형제 반환
GuideIndex prevSibling = repository.findByPathContainingAndDepthAndOrder(parentPath, targetIndex.getDepth(), targetIndex.getOrder() - 1);
if(repository.findAllByPathContainingAndDepth(prevSibling.getPath(), prevSibling.getDepth() + 1).size() == 0){
GuideIndex prevSibling = repository.findByPathContainingAndDepthAndOrderAndLocale(parentPath, targetIndex.getDepth(), targetIndex.getOrder() - 1, targetIndex.getLocale());
if(repository.findAllByPathContainingAndDepthAndLocale(prevSibling.getPath(), prevSibling.getDepth() + 1, prevSibling.getLocale()).size() == 0){
return prevSibling;
} else { // 이전 형제의 자식이 있을 경우 가장 마지막 자식 반환
return getLastChildIndex(prevSibling);
......@@ -54,9 +54,9 @@ public class GuideIndexService {
}
public GuideIndex getLastChildIndex(GuideIndex targetIndex) throws Exception{
GuideIndex lastChild = repository.findAllByPathContainingAndDepthOrderByOrderDesc(targetIndex.getPath(), targetIndex.getDepth() + 1).get(0);
GuideIndex lastChild = repository.findAllByPathContainingAndDepthAndLocaleOrderByOrderDesc(targetIndex.getPath(), targetIndex.getDepth() + 1, targetIndex.getLocale()).get(0);
if(repository.findAllByPathContainingAndDepth(lastChild.getPath(), lastChild.getDepth() + 1).size() == 0){
if(repository.findAllByPathContainingAndDepthAndLocale(lastChild.getPath(), lastChild.getDepth() + 1, lastChild.getLocale()).size() == 0){
return lastChild;
} else {
return getLastChildIndex(lastChild);
......@@ -76,25 +76,29 @@ public class GuideIndexService {
// child가 있으면 order == 0 인 자식 반환 (onlySibling == true 일 경우 패스하여 형제 반환으로 넘어감)
if(!onlySibling){
nextIndex = repository.findByPathContainingAndDepthAndOrder(path, targetIndex.getDepth() + 1, 0);
nextIndex = repository.findByPathContainingAndDepthAndOrderAndLocale(path, targetIndex.getDepth() + 1, 0, targetIndex.getLocale());
}
// child가 없으면 다음 형제 반환
if(nextIndex == null){
nextIndex = repository.findByPathContainingAndDepthAndOrder(parentPath, targetIndex.getDepth(), targetIndex.getOrder() + 1);
nextIndex = repository.findByPathContainingAndDepthAndOrderAndLocale(parentPath, targetIndex.getDepth(), targetIndex.getOrder() + 1, targetIndex.getLocale());
}
// child가 없고, 다음 형제 없는 경우, 부모 guide의 nextIndex 탐색
if(nextIndex == null && targetIndex.getDepth() != 1) {
GuideIndex parentIndex = repository.findByPath(parentPath);
GuideIndex parentIndex = repository.findByPathAndLocale(parentPath, targetIndex.getLocale());
nextIndex = getNextIndex(parentIndex, true);
}
return nextIndex;
}
public List<GuideIndex> getAll() throws Exception{
return repository.findAllByOrderByOrder();
public List<GuideIndex> getAll(String locale) throws Exception{
if(locale == null){
return repository.findAllByOrderByOrder();
} else {
return repository.findAllByLocaleOrderByOrder(locale);
}
}
@Transactional
......@@ -141,7 +145,7 @@ public class GuideIndexService {
// 인덱스 증가해야 할 경우 (type == 1)
if(type == 1){
if(targetIndex.getDepth() == 1){
List<GuideIndex> siblings = repository.findAllByDepthOrderByOrder(1);
List<GuideIndex> siblings = repository.findAllByDepthAndLocaleOrderByOrder(1, targetIndex.getLocale());
siblings.forEach(el -> {
if(el.getOrder() >= targetIndex.getOrder()){
el.setOrder(el.getOrder() + 1);
......@@ -149,7 +153,7 @@ public class GuideIndexService {
}
});
} else {
List<GuideIndex> siblings = repository.findAllByPathContainingAndDepth(parentPath, targetIndex.getDepth());
List<GuideIndex> siblings = repository.findAllByPathContainingAndDepthAndLocale(parentPath, targetIndex.getDepth(), targetIndex.getLocale());
siblings.forEach(el -> {
if(el.getOrder() >= targetIndex.getOrder()){
el.setOrder(el.getOrder() + 1);
......@@ -164,7 +168,7 @@ public class GuideIndexService {
// 인덱스 감소해야 할 경우 (type == -1)
if(type == -1){
if(targetIndex.getDepth() == 1){
List<GuideIndex> siblings = repository.findAllByDepthOrderByOrder(1);
List<GuideIndex> siblings = repository.findAllByDepthAndLocaleOrderByOrder(1, targetIndex.getLocale());
siblings.forEach(el -> {
if(el.getOrder() > targetIndex.getOrder()){
el.setOrder(el.getOrder() - 1);
......@@ -172,7 +176,7 @@ public class GuideIndexService {
}
});
} else {
List<GuideIndex> siblings = repository.findAllByPathContainingAndDepth(parentPath, targetIndex.getDepth());
List<GuideIndex> siblings = repository.findAllByPathContainingAndDepthAndLocale(parentPath, targetIndex.getDepth(), targetIndex.getLocale());
siblings.forEach(el -> {
if(el.getOrder() > targetIndex.getOrder()){
el.setOrder(el.getOrder() - 1);
......
import ko from "./messages/ko.js";
import en from "./messages/en.js";
export default {
locale: "ko",
fallbackLocale: "ko",
messages: { ko, en },
};
export default [
{
code: "ko",
name: "Korean",
iso: "ko-KR",
},
{
code: "en",
name: "English",
iso: "en-US",
},
];
export default {
"서비스 가이드": "Service Guide",
"홈": "Home",
}
\ No newline at end of file
export default {
"서비스 가이드": "서비스 가이드",
"홈": "홈",
}
\ No newline at end of file
......@@ -58,7 +58,7 @@
active-class="active"
:class="{active: $route.path === '/'}"
>
<v-list-item-title></v-list-item-title>
<v-list-item-title>{{$t('홈')}}</v-list-item-title>
</v-list-item>
</v-list>
......@@ -148,7 +148,11 @@
</div>
</div>
<v-icon @click="showSearch = !showSearch" class="header-icon">{{showSearch ? 'mdi-close' : 'mdi-magnify'}}</v-icon>
<v-icon @click="showSearch = !showSearch" class="search-icon">{{showSearch ? 'mdi-close' : 'mdi-magnify'}}</v-icon>
<span @click="setLocale" class="locale-icon">
<span class="locale-icon__badge">{{$i18n.locale}}</span>
<v-icon class="ml-4 ">mdi-web</v-icon>
</span>
<v-app-bar-nav-icon class="mobile-show" v-if="!drawer" @click.stop="drawer = !drawer" />
</v-row>
......@@ -166,8 +170,15 @@
<v-row class="pa-10 pt-0 justify-space-around" no-gutters style="width: 100%; height: calc(100% - 68px);">
<v-col cols="5" style="height: 100%;">
<v-subheader>인덱스 목록</v-subheader>
<v-col cols="5" style="height: 100%; position: relative;">
<v-subheader>
인덱스 목록
<v-spacer></v-spacer>
<span @click="setLocale" class="locale-icon">
<span class="locale-icon__badge">{{$i18n.locale}}</span>
<v-icon>mdi-web</v-icon>
</span>
</v-subheader>
<v-list v-if="editModeList && !loadingPageList">
<tree
:items="editModeList"
......@@ -324,6 +335,9 @@ export default{
},
},
methods:{
setLocale() {
this.$i18n.setLocale(this.$i18n.locale === 'ko' ? 'en' : 'ko')
},
openIndex() {
let route = this.$router.resolve({path: '/'});
window.open(route.href, '_self');
......@@ -337,11 +351,14 @@ export default{
this.selectedIndex = guide
this.$router.push('/' + guide.id)
},
async getGuideIndex(){
this.loadingPageList = true
await this.$axios.get('/guide-index/all')
await this.$axios.get('/guide-index/all', {
params:{
locale: this.$i18n.locale
}
})
.then(res => {
this.rawIndexList = res.data;
this.getIndexTree(JSON.parse(JSON.stringify(res.data)));
......@@ -494,7 +511,7 @@ export default{
const searchContainer = document.querySelector('.search-container')
const searchInput = document.querySelector('.search-input')
const searchResult = document.querySelector('.search-result')
const searchBtn = document.querySelector('.header-icon')
const searchBtn = document.querySelector('.search-icon')
const isClickInside = [searchContainer, searchInput, searchResult, searchBtn].some(item =>
item.contains(e.target)
......@@ -565,6 +582,9 @@ export default{
},
watch:{
'$i18n.locale'(val){
this.getGuideIndex()
},
'$store.state.guideNavigator'() {
this.navPositionList = this.$store.state.guideNavigator.map((nav) => nav.position)
},
......@@ -582,12 +602,28 @@ export default{
document.getElementsByTagName('html')[0].classList.remove('search-on')
window.removeEventListener('click', this.clickOutsideEvent);
}
}
},
},
}
</script>
<style lang="scss">
.app-bar-wrap, .edit-dialog-container {
.locale-icon {
position: relative;
cursor: pointer;
.locale-icon__badge {
position: absolute;
right: 20px;
top: -6px;
font-size: 0.75rem;
text-transform: uppercase;
font-weight: 700;
}
}
}
.v-dialog {
width: 70vw !important;
height: 80vh;
......@@ -669,7 +705,7 @@ html.search-on {
z-index: 9;
position: absolute;
top: 48px;
right: 96px;
right: 136px;
border: 1px solid rgb(238, 238, 238);
border-top: none;
border-radius: 0 0 28px 28px;
......@@ -698,7 +734,7 @@ html.search-on {
@media screen and (min-width: 1264px) {
.search-result {
right: 48px;
right: 88px;
}
}
......
import colors from 'vuetify/es5/util/colors'
import i18nConfig from "./i18n/config";
import locales from "./i18n/locales";
export default {
......@@ -57,8 +58,17 @@ export default {
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
'nuxt-healthcheck',
'@nuxtjs/markdownit'
'@nuxtjs/markdownit',
'nuxt-i18n',
],
i18n:{
seo: true,
locales,
defaultLocale: 'ko',
vueI18n: i18nConfig,
skipSettingLocaleOnNavigate: true,
},
// Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify
vuetify: {
......
This diff is collapsed.
......@@ -16,6 +16,7 @@
"markdown-it-div": "^1.1.0",
"nuxt": "^2.15.8",
"nuxt-healthcheck": "^1.0.1",
"nuxt-i18n": "^6.28.1",
"sass-loader": "^10.2.0",
"vue": "^2.7.10",
"vue-no-ssr": "^1.1.1",
......
......@@ -171,8 +171,8 @@ export default {
async getGuideContents() {
const contentKey = `${this.guide.path.substring(0,this.guide.path.length-1)}.md`
await this.$axios.get("https://api.github.com/repos/vazilcompany/vridge-docs/contents/guide/ko/" + contentKey, {
await this.$axios.get(
`https://api.github.com/repos/vazilcompany/vridge-docs/contents/guide/${this.$i18n.locale}/` + contentKey, {
headers:{
Authorization: 'token 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'
}
......@@ -183,24 +183,10 @@ export default {
})
.catch(err=>{
this.guide.content = ''
console.log(err)
console.log('가이드 로드 실패')
})
},
parsingContentTitle(content) {
let keyArray = content.contentKey.replace('.md','').split('/')
let titleKey = ''
if(keyArray[0] !== keyArray[1]) {
for(let i = 0; i < keyArray.length - 1; i++) {
titleKey += keyArray[i] + '_'
}
titleKey += content.title
} else {
titleKey = content.title
}
return titleKey
},
getBreadcrumbs(){
let items = []
let paths = this.guide.path.substring(0, this.guide.path.length-1).split('/')
......
......@@ -2,7 +2,7 @@
<div class="guide-wrap-container">
<v-container class="guide-wrap">
<v-row no-gutters align="center" justify="center" class="guide-wrap-header">
<h1 class="font-weight-bold">서비스 가이드</h1>
<h1 class="font-weight-bold">{{$t('서비스 가이드')}}</h1>
</v-row>
<v-row no-gutters class="guide-content">
......@@ -29,7 +29,11 @@ export default {
}),
methods:{
async getGuideIndex(){
await this.$axios.get('http://localhost:5000/guide-index/all')
await this.$axios.get('/guide-index/all', {
params:{
locale: this.$i18n.locale
}
})
.then(res => {
this.getIndexTree(JSON.parse(JSON.stringify(res.data)));
})
......@@ -77,6 +81,9 @@ export default {
this.getGuideIndex()
},
watch:{
'$i18n.locale'(){
this.getGuideIndex()
}
}
}
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment