용어집 수정

This commit is contained in:
Dang 2025-02-27 11:23:56 +09:00
parent bd91e0a72d
commit 3d41dc7730
6 changed files with 128 additions and 39 deletions

File diff suppressed because one or more lines are too long

View File

@ -21,7 +21,7 @@
</div>
<!-- 카테고리 중복 -->
<div class="invalid-feedback" :class="isCateAlert ? 'display-block' : ''">
카테고리 중복입니다.
카테고리중복이거나 공백이면 안됩니다. 확인해주세요.
</div>
</div>
</div>

View File

@ -1,8 +1,8 @@
<template>
<li class="mt-5 card p-5">
<DictWrite
v-if="isWriteVisible"
@close="isWriteVisible = false"
v-if="writeStore.isItemActive(item.WRDDICSEQ)"
@close="writeStore.closeAll();"
:dataList="cateList"
@addWord="editWord"
:NumValue="item.WRDDICSEQ"
@ -35,7 +35,9 @@
class="rounded-circle user-avatar"
:src="getProfileImage(item.author.profileImage)"
alt="최초 작성자"
:style="{ borderColor: item.author.color}"/>
:style="{ borderColor: item.author.color}"
@error="setDefaultImage"
/>
</div>
<div>
<p class="mb-0 small fw-medium">{{ formattedDate(item.author.createdAt) }}</p>
@ -52,7 +54,9 @@
class="rounded-circle user-avatar"
:src="getProfileImage(item.lastEditor.profileImage)"
alt="최근 작성자"
:style="{ borderColor: item.lastEditor.color}"/>
:style="{ borderColor: item.lastEditor.color}"
@error="setDefaultImage"
/>
</div>
<div>
<p class="mb-0 small fw-medium">{{ formattedDate(item.lastEditor.updatedAt) }}</p>
@ -62,7 +66,7 @@
</div>
<div class="edit-btn" v-if="userStore.user.role !== 'ROLE_ADMIN'">
<EditBtn @click="toggleWriteVisible" />
<EditBtn @click="writeStore.toggleItem(item.WRDDICSEQ)" />
</div>
</li>
</template>
@ -75,8 +79,10 @@ import EditBtn from '@/components/button/EditBtn.vue';
import $api from '@api';
import DictWrite from './DictWrite.vue';
import { formattedDate } from "@/common/formattedDate";
import { useUserInfoStore } from '@s/useUserInfoStore';
import { useWriteVisibleStore } from '@s/writeVisible';
const writeStore = useWriteVisibleStore();
//
const userStore = useUserInfoStore();
@ -107,13 +113,13 @@ const props = defineProps({
const emit = defineEmits(['update:cateList','refreshWordList', 'updateChecked']);
//
const isWriteVisible = ref(false);
// const isWriteVisible = ref(false);
// toggle
const toggleWriteVisible = () => {
isWriteVisible.value = !isWriteVisible.value;
};
// const toggleWriteVisible = () => {
// isWriteVisible.value = !isWriteVisible.value;
// };
//
// const addCategory = (data) => {
@ -176,7 +182,8 @@ const editWord = (data) => {
.then((res) => {
if (res.data.data === 1) {
toastStore.onToast('✅ 용어가 수정되었습니다.', 's');
isWriteVisible.value = false;
// isWriteVisible.value = false;
writeStore.closeAll();
emit('refreshWordList');
} else {
console.warn('⚠️ 서버 응답이 예상과 다릅니다:', res.data);
@ -191,9 +198,6 @@ const editWord = (data) => {
const baseUrl = $api.defaults.baseURL.replace(/api\/$/, '');
//
// const formatDate = (dateString) => new Date(dateString).toLocaleString();
//
const defaultProfile = "/img/icons/icon.png";
@ -201,6 +205,10 @@ const getProfileImage = (profilePath) => {
return profilePath && profilePath.trim() ? `${baseUrl}upload/img/profile/${profilePath}` : defaultProfile;
};
const setDefaultImage = (event) => {
event.target.src = defaultProfile;
};
//
const toggleCheck = (event) => {

View File

@ -65,6 +65,7 @@ import QEditor from '@/components/editor/QEditor.vue';
import FormInput from '@/components/input/FormInput.vue';
import FormSelect from '@/components/input/FormSelect.vue';
import PlusBtn from '../button/PlusBtn.vue';
// import { clearConfig } from 'dompurify';
// import { useUserInfoStore } from '@s/useUserInfoStore';
//
@ -153,21 +154,33 @@ const onChange = (newValue) => {
//
const saveWord = () => {
//validation
console.log('computedTitle.value', computedTitle.value);
let computedTitleTrim;
if(computedTitle.value != undefined){
computedTitleTrim = computedTitle.value.trim()
}
//
if(computedTitle.value == undefined){
if(computedTitleTrim == undefined || computedTitleTrim == ''){
wordTitleAlert.value = true;
return;
} else {
wordTitleAlert.value = false;
}
//
let inserts = [];
if(inserts.length === 0 && content.value?.ops?.length > 0){
inserts = content.value.ops.map(op => op.insert.trim());
}
//
if(content.value == ''){
if(content.value == '' || inserts.join('') === ''){
wordContentAlert.value = true;
return;
}
const wordData = {
id: props.NumValue || null,
title: computedTitle.value,
@ -181,12 +194,26 @@ const saveWord = () => {
// focusout
const handleCategoryFocusout = (value) => {
const valueTrim = value.trim();
const existingCategory = props.dataList.find(item => item.label === value);
const existingCategory = props.dataList.find(item => item.label === valueTrim);
// console.log('existingCategory', existingCategory);
if (existingCategory) {
// console.log(' :', value);
//
if(valueTrim == ''){
//alert(' ');
addCategoryAlert.value = true;
// focus
setTimeout(() => {
const inputElement = categoryInputRef.value?.$el?.querySelector('input');
if (inputElement) {
inputElement.focus();
}
}, 0);
}else if (existingCategory) {
addCategoryAlert.value = true;
// focus

View File

@ -0,0 +1,48 @@
/*
작성자 : 조대원
작성일 : 2025-02-27
수정자 :
수정일 :
설명 : 용어집 작성, 수정 공통관리
*/
import { ref } from 'vue';
import { defineStore } from 'pinia';
export const useWriteVisibleStore = defineStore('writeVisible', () => {
// 현재 열려있는 항목의 ID를 저장 (열린 것이 없으면 null)
const activeItemId = ref(null);
// 특정 항목의 열림/닫힘 상태 확인
function isItemActive(itemId) {
return activeItemId.value === itemId;
}
// 항목 토글 - 현재 열려있으면 닫고, 닫혀있으면 열기
function toggleItem(itemId) {
if (activeItemId.value === itemId) {
// 현재 열려있는 항목을 다시 클릭하면 닫기
activeItemId.value = null;
} else {
// 다른 항목 클릭시 해당 항목을 열고 이전 항목은 자동으로 닫힘
activeItemId.value = itemId;
}
}
// 특정 항목 강제로 열기 (다른 항목은 닫힘)
function setActiveItem(itemId) {
activeItemId.value = itemId;
}
// 모든 항목 닫기
function closeAll() {
activeItemId.value = null;
}
return {
activeItemId,
isItemActive,
toggleItem,
setActiveItem,
closeAll
};
});

View File

@ -14,7 +14,7 @@
<!-- 단어 갯수, 작성하기 -->
<div class="mt-4">
단어 : {{ total }}
<WriteButton @click="toggleWriteForm" />
<WriteButton @click="writeStore.toggleItem(999999)" />
</div>
<!-- -->
@ -28,8 +28,8 @@
</div>
<!-- 작성 -->
<div v-if="isWriteVisible" class="mt-5">
<DictWrite @close="isWriteVisible = false" :dataList="cateList" @addWord="addWord"/>
<div v-if="writeStore.isItemActive(999999)" class="mt-5">
<DictWrite @close="writeStore.closeAll()" :dataList="cateList" @addWord="addWord"/>
</div>
</div>
@ -78,9 +78,13 @@
import commonApi from '@/common/commonApi';
import { useToastStore } from '@s/toastStore';
import { useUserInfoStore } from '@s/useUserInfoStore';
import { useWriteVisibleStore } from '@s/writeVisible';
//
const writeStore = useWriteVisibleStore();
//
const userStore = useUserInfoStore();
// const userStore = useUserInfoStore();
const { appContext } = getCurrentInstance();
const $common = appContext.config.globalProperties.$common;
@ -118,7 +122,7 @@
const searchText = ref('');
//
const isWriteVisible = ref(false);
// const isWriteVisible = ref(false);
//
onMounted(() => {
@ -168,9 +172,9 @@
}
// toggle
const toggleWriteForm = () => {
isWriteVisible.value = !isWriteVisible.value;
};
// const toggleWriteForm = () => {
// isWriteVisible.value = !isWriteVisible.value;
// };
//
// const addCategory = (data) =>{
@ -197,15 +201,14 @@
const addWord = (wordData, data) => {
let category = null;
//
const existingCategory = cateList.value.find(item => item.label === data);
if (existingCategory) {
console.log('카테고리 중복');
const existingCategory = cateList.value.find(item => item.label === data.trim());
if (existingCategory) {
//
category = existingCategory.label == '' ? wordData.category : existingCategory.value;
} else {
//
console.log('카테고리 없음');
// console.log(' ');
const lastCategory = cateList.value[cateList.value.length - 1];
category = lastCategory ? lastCategory.value + 1 : 600101;
}
@ -224,7 +227,8 @@
axios.post('worddict/insertWord', payload).then(res => {
if (res.data.status === 'OK') {
toastStore.onToast('용어가 등록 되었습니다.', 's');
isWriteVisible.value = false;
// isWriteVisible.value = false;
writeStore.closeAll();
getwordList();
const newCategory = { label: data, value: category }; // data
cateList.value = [newCategory, ...cateList.value];
@ -234,7 +238,8 @@
axios.post('worddict/insertWord', payload).then(res => {
if (res.data.status === 'OK') {
toastStore.onToast('용어가 등록 되었습니다.', 's');
isWriteVisible.value = false;
// isWriteVisible.value = false;
writeStore.closeAll();
getwordList();
}
});
@ -268,7 +273,8 @@
.then(res => {
if (res.data.status == 'OK') {
toastStore.onToast('용어 삭제가 완료되었습니다.', 's');
isWriteVisible.value = false;
// isWriteVisible.value = false;
writeStore.closeAll();
getwordList();
//
@ -277,7 +283,7 @@
}
})
.catch(error => {
console.error('삭제 요청 중 오류 발생:', error);
// console.error(' :', error);
toastStore.onToast('오류가 발생했습니다. 다시 시도해주세요.', 'e');
});