용어집 수정
This commit is contained in:
parent
fc59cc4e5a
commit
72c2865b0b
@ -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);
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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']);
|
||||||
|
|
||||||
@ -92,6 +99,9 @@ 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>
|
||||||
|
|||||||
@ -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();
|
|
||||||
//카테고리 리스트 다시 조회 해야야함
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// 체크 상태 업데이트
|
// 체크 상태 업데이트
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user