용어집 수정

This commit is contained in:
Dang 2025-02-25 14:08:33 +09:00
parent fc59cc4e5a
commit 72c2865b0b
4 changed files with 161 additions and 103 deletions

View File

@ -14,10 +14,15 @@
:placeholder="title" :placeholder="title"
:disabled="disabled" :disabled="disabled"
:min="min" :min="min"
@focusout="$emit('focusout', modelValue)"
/> />
<div class="invalid-feedback" :class="isAlert ? 'display-block' : ''"> <div class="invalid-feedback" :class="isAlert ? 'display-block' : ''">
{{ title }} 확인해주세요. {{ title }} 확인해주세요.
</div> </div>
<!-- 카테고리 중복 -->
<div class="invalid-feedback" :class="isCateAlert ? 'display-block' : ''">
카테고리 중복입니다.
</div>
</div> </div>
</div> </div>
</template> </template>
@ -57,6 +62,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
isCateAlert : {
type :Boolean,
default: false,
},
isLabel : { isLabel : {
type: Boolean, type: Boolean,
default: true, default: true,
@ -73,7 +82,7 @@ const props = defineProps({
}); });
// Emits // Emits
const emits = defineEmits(['update:modelValue']); const emits = defineEmits(['update:modelValue', 'focusout']);
// `inputValue` // `inputValue`
const inputValue = ref(props.modelValue); const inputValue = ref(props.modelValue);

View File

@ -4,12 +4,12 @@
v-if="isWriteVisible" v-if="isWriteVisible"
@close="isWriteVisible = false" @close="isWriteVisible = false"
:dataList="cateList" :dataList="cateList"
@addCategory="addCategory"
@addWord="editWord" @addWord="editWord"
:NumValue="item.WRDDICSEQ" :NumValue="item.WRDDICSEQ"
:formValue="item.WRDDICCAT" :formValue="item.WRDDICCAT"
:titleValue="item.WRDDICTTL" :titleValue="item.WRDDICTTL"
:contentValue="item.WRDDICCON" :contentValue="item.WRDDICCON"
:isDisabled="userStore.user.role !== 'ROLE_ADMIN'"
/> />
<div v-else> <div v-else>
@ -38,7 +38,7 @@
:style="{ borderColor: item.author.color}"/> :style="{ borderColor: item.author.color}"/>
</div> </div>
<div> <div>
<p class="mb-0 small fw-medium">{{ formatDate(item.author.createdAt) }}</p> <p class="mb-0 small fw-medium">{{ formattedDate(item.author.createdAt) }}</p>
</div> </div>
</div> </div>
</div> </div>
@ -55,13 +55,13 @@
:style="{ borderColor: item.lastEditor.color}"/> :style="{ borderColor: item.lastEditor.color}"/>
</div> </div>
<div> <div>
<p class="mb-0 small fw-medium">{{ formatDate(item.lastEditor.updatedAt) }}</p> <p class="mb-0 small fw-medium">{{ formattedDate(item.lastEditor.updatedAt) }}</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="edit-btn"> <div class="edit-btn" v-if="userStore.user.role !== 'ROLE_ADMIN'">
<EditBtn @click="toggleWriteVisible" /> <EditBtn @click="toggleWriteVisible" />
</div> </div>
</li> </li>
@ -74,6 +74,7 @@ import { ref, toRefs, getCurrentInstance, } from 'vue';
import EditBtn from '@/components/button/EditBtn.vue'; import EditBtn from '@/components/button/EditBtn.vue';
import $api from '@api'; import $api from '@api';
import DictWrite from './DictWrite.vue'; import DictWrite from './DictWrite.vue';
import { formattedDate } from "@/common/formattedDate";
import { useUserInfoStore } from '@s/useUserInfoStore'; import { useUserInfoStore } from '@s/useUserInfoStore';
@ -98,9 +99,9 @@ const props = defineProps({
}); });
// //
const localCateList = ref([...props.cateList]); // const localCateList = ref([...props.cateList]);
// //
const selectedCategory = ref(''); // const selectedCategory = ref('');
// cateList emit // cateList emit
const emit = defineEmits(['update:cateList','refreshWordList', 'updateChecked']); const emit = defineEmits(['update:cateList','refreshWordList', 'updateChecked']);
@ -115,41 +116,41 @@ const toggleWriteVisible = () => {
}; };
// //
const addCategory = (data) => { // const addCategory = (data) => {
try { // try {
const lastCategory = localCateList.value.length > 0 // const lastCategory = localCateList.value.length > 0
? localCateList.value[localCateList.value.length - 1] // ? localCateList.value[localCateList.value.length - 1]
: null; // : null;
const newValue = lastCategory ? lastCategory.value + 1 : 600101; // const newValue = lastCategory ? lastCategory.value + 1 : 600101;
// console.log('lastCategory', lastCategory); // // // console.log('lastCategory', lastCategory);
// console.log('newValue', newValue); // // // console.log('newValue', newValue);
axios.post('worddict/insertCategory', { // axios.post('worddict/insertCategory', {
CMNCODNAM: data // CMNCODNAM: data
}).then(res => { // }).then(res => {
if(res.data.data === 1){ // if(res.data.data === 1){
toastStore.onToast('카테고리가 추가 등록 되었습니다.', 's'); // toastStore.onToast(' .', 's');
const newCategory = { label: data, value: newValue }; // const newCategory = { label: data, value: newValue };
localCateList.value = [newCategory, ...localCateList.value]; // localCateList.value = [newCategory, ...localCateList.value];
selectedCategory.value = newCategory.value; // selectedCategory.value = newCategory.value;
// console.log('newCategory', newCategory); // // // console.log('newCategory', newCategory);
// console.log('localCateList.value', localCateList.value); // // // console.log('localCateList.value', localCateList.value);
// console.log('selectedCategory.value', selectedCategory.value); // // // console.log('selectedCategory.value', selectedCategory.value);
// // // //
emit('update:cateList', localCateList.value); // emit('update:cateList', localCateList.value);
} else if(res.data.message == '이미 존재하는 카테고리명입니다.') { // } else if(res.data.message == ' .') {
toastStore.onToast(res.data.message, 'e'); // toastStore.onToast(res.data.message, 'e');
} // }
}).catch(err => { // }).catch(err => {
console.error('카테고리 추가 중 오류:', err); // console.error(' :', err);
}); // });
} catch (err) { // } catch (err) {
console.error('카테고리 추가 함수 오류:', err); // console.error(' :', err);
} // }
} // }
// //
@ -191,7 +192,7 @@ const editWord = (data) => {
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, ''); const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
// //
const formatDate = (dateString) => new Date(dateString).toLocaleString(); // const formatDate = (dateString) => new Date(dateString).toLocaleString();
// //
const defaultProfile = "/img/icons/icon.png"; const defaultProfile = "/img/icons/icon.png";

View File

@ -13,20 +13,27 @@
:disabled="isDisabled" :disabled="isDisabled"
/> />
</div> </div>
<div class="col-2 btn-margin"> <div class="col-2 btn-margin" v-if="!isDisabled">
<PlusBtn v-if="userStore.user.role == 'ROLE_ADMIN'" @click="toggleInput"/> <PlusBtn @click="toggleInput"/>
</div> </div>
</div> </div>
<div class="row" v-if="showInput"> <div class="row" v-if="showInput">
<div class="col-10"> <div class="col-10">
<FormInput title="카테고리 입력" name="카테고리" @update:modelValue="addCategory = $event" :is-alert="addCategoryAlert"/> <FormInput
ref="categoryInputRef"
title="카테고리 입력"
name="카테고리"
@update:modelValue="addCategory = $event"
:is-cate-alert="addCategoryAlert"
@focusout="handleCategoryFocusout(addCategory)"
/>
</div> </div>
<div class="col-2 btn-margin"> <!-- <div class="col-2 btn-margin">
<button class="btn btn-primary btn-icon" @click="saveInput"> <button class="btn btn-primary btn-icon" @click="saveInput">
<i class="bx bx-check"></i> <i class="bx bx-check"></i>
</button> </button>
</div> </div> -->
</div> </div>
</div> </div>
<div class="dict-w"> <div class="dict-w">
@ -58,13 +65,13 @@ import QEditor from '@/components/editor/QEditor.vue';
import FormInput from '@/components/input/FormInput.vue'; import FormInput from '@/components/input/FormInput.vue';
import FormSelect from '@/components/input/FormSelect.vue'; import FormSelect from '@/components/input/FormSelect.vue';
import PlusBtn from '../button/PlusBtn.vue'; import PlusBtn from '../button/PlusBtn.vue';
import { useUserInfoStore } from '@s/useUserInfoStore'; // import { useUserInfoStore } from '@s/useUserInfoStore';
// //
const userStore = useUserInfoStore(); // const userStore = useUserInfoStore();
// disabled // disabled
const isDisabled = computed(() => userStore.user.role !== 'ROLE_ADMIN'); // const isDisabled = computed(() => userStore.user.role !== 'ROLE_ADMIN');
const emit = defineEmits(['close','addCategory','addWord']); const emit = defineEmits(['close','addCategory','addWord']);
@ -83,15 +90,18 @@ const addCategoryAlert = ref(false);
const selectCategory = ref(''); const selectCategory = ref('');
// //
const computedTitle = computed(() => const computedTitle = computed(() =>
wordTitle.value === '' ? props.titleValue : wordTitle.value wordTitle.value === '' ? props.titleValue : wordTitle.value
); );
// //
const selectedCategory = computed(() => const selectedCategory = computed(() =>
selectCategory.value === '' ? props.formValue : selectCategory.value selectCategory.value === '' ? props.formValue : selectCategory.value
); );
// ref
const categoryInputRef = ref(null);
const props = defineProps({ const props = defineProps({
dataList: { dataList: {
type: Array, type: Array,
@ -106,7 +116,11 @@ const props = defineProps({
titleValue : { titleValue : {
type:String, type:String,
},contentValue : { },contentValue : {
type:String type:String,
},
isDisabled: {
type: Boolean,
default: false
} }
}); });
@ -120,17 +134,17 @@ const toggleInput = () => {
// //
const saveInput = () => { // const saveInput = () => {
if(addCategory.value == ''){ // if(addCategory.value == ''){
addCategoryAlert.value = true; // addCategoryAlert.value = true;
return; // return;
}else { // }else {
addCategoryAlert.value = false; // addCategoryAlert.value = false;
} // }
// console.log(' !',addCategory.value); // console.log(' !',addCategory.value);
emit('addCategory', addCategory.value); // emit('addCategory', addCategory.value);
// showInput.value = false; // showInput.value = false;
}; // };
const onChange = (newValue) => { const onChange = (newValue) => {
selectCategory.value = newValue.target.value; selectCategory.value = newValue.target.value;
@ -138,18 +152,12 @@ const onChange = (newValue) => {
// //
const saveWord = () => { const saveWord = () => {
// if(addCategory.value == ''){
// addCategoryAlert.value = true;
// return;
// }else {
// addCategoryAlert.value = false;
// }
//validation //validation
console.log('computedTitle.value', computedTitle.value);
// //
if(computedTitle.value == '' || computedTitle.length == 0){ if(computedTitle.value == undefined){
wordTitleAlert.value = true; wordTitleAlert.value = true;
return; return;
} }
@ -166,8 +174,35 @@ const saveWord = () => {
category: selectedCategory.value, category: selectedCategory.value,
content: content.value, content: content.value,
}; };
emit('addWord', wordData ,addCategory.value );
emit('addWord', wordData, addCategory.value);
}
// focusout
const handleCategoryFocusout = (value) => {
const existingCategory = props.dataList.find(item => item.label === value);
// console.log('existingCategory', existingCategory);
if (existingCategory) {
// console.log(' :', value);
addCategoryAlert.value = true;
// focus
setTimeout(() => {
const inputElement = categoryInputRef.value?.$el?.querySelector('input');
if (inputElement) {
inputElement.focus();
}
}, 0);
} else {
addCategoryAlert.value = false;
}
}; };
</script> </script>
<style scoped> <style scoped>
@ -180,4 +215,4 @@ const saveWord = () => {
margin-top: 2.5rem margin-top: 2.5rem
} }
} }
</style> </style>

View File

@ -1,6 +1,5 @@
<template> <template>
<div class="container-xxl flex-grow-1 container-p-y"> <div class="container-xxl flex-grow-1 container-p-y">
<!-- {{ userStore.user.role == 'ROLE_ADMIN' ? '관리자' : '일반인'}} -->
<div class="card p-5"> <div class="card p-5">
<!-- 타이틀, 검색 --> <!-- 타이틀, 검색 -->
<div class="row"> <div class="row">
@ -30,7 +29,7 @@
<!-- 작성 --> <!-- 작성 -->
<div v-if="isWriteVisible" class="mt-5"> <div v-if="isWriteVisible" class="mt-5">
<DictWrite @close="isWriteVisible = false" :dataList="cateList" @addCategory="addCategory" @addWord="addWord"/> <DictWrite @close="isWriteVisible = false" :dataList="cateList" @addWord="addWord"/>
</div> </div>
</div> </div>
@ -174,30 +173,34 @@
}; };
// //
const addCategory = (data) =>{ // const addCategory = (data) =>{
const lastCategory = cateList.value[cateList.value.length - 1]; // const lastCategory = cateList.value[cateList.value.length - 1];
const newValue = lastCategory ? lastCategory.value + 1 : 600101; // const newValue = lastCategory ? lastCategory.value + 1 : 600101;
const newCategory = { label: data, value: newValue }; // const newCategory = { label: data, value: newValue };
cateList.value = [newCategory, ...cateList.value];
selectedCategory.value = newCategory.value;
// axios.post('worddict/insertCategory',{
// CMNCODNAM: data
// }).then(res => {
// if(res.data.data == '1'){
// toastStore.onToast(' .', 's');
// const newCategory = { label: data, value: newValue };
// cateList.value = [newCategory, ...cateList.value]; // cateList.value = [newCategory, ...cateList.value];
// selectedCategory.value = newCategory.value; // selectedCategory.value = newCategory.value;
// } else if(res.data.message == ' .') { //// axios.post('worddict/insertCategory',{
// toastStore.onToast(res.data.message, 'e'); //// CMNCODNAM: data
// } //// }).then(res => {
// }) //// if(res.data.data == '1'){
} //// toastStore.onToast(' .', 's');
//// const newCategory = { label: data, value: newValue };
//// cateList.value = [newCategory, ...cateList.value];
//// selectedCategory.value = newCategory.value;
//// } else if(res.data.message == ' .') {
//// toastStore.onToast(res.data.message, 'e');
//// }
//// })
// }
//
const addWord = (wordData, data) => { const addWord = (wordData, data) => {
let category = null; let category = null;
// //
const existingCategory = cateList.value.find(item => item.label === data); const existingCategory = cateList.value.find(item => item.label === data);
if (existingCategory) { if (existingCategory) {
console.log('카테고리 중복');
// //
category = existingCategory.label == '' ? wordData.category : existingCategory.value; category = existingCategory.label == '' ? wordData.category : existingCategory.value;
} else { } else {
@ -208,6 +211,7 @@
} }
sendWordRequest(category, wordData, data, !existingCategory); sendWordRequest(category, wordData, data, !existingCategory);
}; };
const sendWordRequest = (category, wordData, data, isNewCategory) => { const sendWordRequest = (category, wordData, data, isNewCategory) => {
const payload = { const payload = {
WRDDICCAT: category, WRDDICCAT: category,
@ -216,17 +220,26 @@
}; };
if (isNewCategory) { if (isNewCategory) {
payload.CMNCODNAM = data; // payload.CMNCODNAM = data;
axios.post('worddict/insertWord', payload).then(res => {
if (res.data.status === 'OK') {
toastStore.onToast('용어가 등록 되었습니다.', 's');
isWriteVisible.value = false;
getwordList();
const newCategory = { label: data, value: category }; // data
cateList.value = [newCategory, ...cateList.value];
}
});
} else {
axios.post('worddict/insertWord', payload).then(res => {
if (res.data.status === 'OK') {
toastStore.onToast('용어가 등록 되었습니다.', 's');
isWriteVisible.value = false;
getwordList();
}
});
} }
axios.post('worddict/insertWord', payload).then(res => { };
if (res.data.status === 'OK') {
toastStore.onToast('용어가 등록 되었습니다.', 's');
isWriteVisible.value = false;
getwordList();
//
}
});
};
// //