용어집 수정

This commit is contained in:
Dang 2025-02-17 15:04:56 +09:00
parent 28cfb7fcc5
commit 62c97e0a18
4 changed files with 149 additions and 59 deletions

View File

@ -40,26 +40,26 @@ const props = defineProps({
required: true, required: true,
}, },
value: { value: {
type: String, type: [String, Number],
default: '0', default: '0',
require: false, require: false,
}, },
isAlert : { isAlert: {
type: Boolean, type: Boolean,
default: false, default: false,
required: false, required: false,
}, },
isLabel : { isLabel: {
type: Boolean, type: Boolean,
default: true, default: true,
required: false, required: false,
}, },
isRow : { isRow: {
type: Boolean, type: Boolean,
default: true, default: true,
required: false, required: false,
}, },
isCommon : { isCommon: {
type: Boolean, type: Boolean,
default: false, default: false,
required: false, required: false,
@ -69,11 +69,19 @@ const props = defineProps({
const emit = defineEmits(['update:data']); const emit = defineEmits(['update:data']);
const selectData = ref(props.value); const selectData = ref(props.value);
// data // props.value watch
watch(() => props.value, (newValue) => {
selectData.value = newValue;
}, { immediate: true });
// data
watch(() => props.data, (newData) => { watch(() => props.data, (newData) => {
if (props.isCommon && newData.length > 0) { if (props.isCommon && newData.length > 0) {
selectData.value = newData[0].value; // value prop '0'()
emit('update:data', selectData.value); if (props.value === '0') {
selectData.value = newData[0].value;
emit('update:data', selectData.value);
}
} }
}, { immediate: true }); }, { immediate: true });
@ -81,4 +89,4 @@ watch(() => props.data, (newData) => {
watch(selectData, (newValue) => { watch(selectData, (newValue) => {
emit('update:data', newValue); emit('update:data', newValue);
}); });
</script> </script>

View File

@ -1,69 +1,146 @@
<template> <template>
<li class="mt-5 card p-5"> <li class="mt-5 card p-5">
<div class="d-flex align-items-center"> <DictWrite
<div class="w-100 d-flex align-items-center"> v-if="isWriteVisible"
<span class="btn btn-primary pe-none">{{ item.category }}</span> @close="isWriteVisible = false"
<strong class="mx-2 w-75">{{ item.WRDDICTTL }}</strong> :dataList="cateList"
</div> @addCategory="addCategory"
<EditBtn /> :formValue="item.WRDDICCAT"
</div> :titleValue="item.WRDDICTTL"
<p class="mt-5" v-html="$common.contentToHtml(item.WRDDICCON)"></p> :contentValue="$common.contentToHtml(item.WRDDICCON)"
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2"> />
<div class="d-flex flex-wrap align-items-center mb-50">
<div class="avatar avatar-sm me-2"> <div v-else>
<img <div class="d-flex align-items-center">
class="rounded-circle user-avatar" <div class="w-100 d-flex align-items-center">
:src="getProfileImage(item.author.profileImage)" <span class="btn btn-primary pe-none">{{ item.category }}</span>
alt="최초 작성자" <strong class="mx-2 w-75">{{ item.WRDDICTTL }}</strong>
:style="{ borderColor: item.author.color}"
/>
</div> </div>
<div> </div>
<p class="mb-0 small fw-medium">{{ formatDate(item.author.createdAt) }}</p> <p class="mt-5" v-html="$common.contentToHtml(item.WRDDICCON)"></p>
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
<div class="d-flex flex-wrap align-items-center mb-50">
<div class="avatar avatar-sm me-2">
<img
class="rounded-circle user-avatar"
:src="getProfileImage(item.author.profileImage)"
alt="최초 작성자"
:style="{ borderColor: item.author.color}"/>
</div>
<div>
<p class="mb-0 small fw-medium">{{ formatDate(item.author.createdAt) }}</p>
</div>
</div>
</div>
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
<div class="d-flex flex-wrap align-items-center mb-50">
<div class="avatar avatar-sm me-2">
<img
class="rounded-circle user-avatar"
:src="getProfileImage(item.lastEditor.profileImage)"
alt="최근 작성자"
:style="{ borderColor: item.lastEditor.color}"/>
</div>
<div>
<p class="mb-0 small fw-medium">{{ formatDate(item.lastEditor.updatedAt) }}</p>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="d-flex justify-content-between flex-wrap gap-2 mb-2">
<div class="d-flex flex-wrap align-items-center mb-50"> <div class="edit-btn">
<div class="avatar avatar-sm me-2"> <EditBtn @click="toggleWriteVisible" />
<img
class="rounded-circle user-avatar"
:src="getProfileImage(item.lastEditor.profileImage)"
alt="최근 작성자"
:style="{ borderColor: item.lastEditor.color}"
/>
</div>
<div>
<p class="mb-0 small fw-medium">{{ formatDate(item.lastEditor.updatedAt) }}</p>
</div>
</div>
</div> </div>
</li> </li>
</template> </template>
<script setup> <script setup>
import axios from "@api";
import { useToastStore } from '@s/toastStore';
import { ref, toRefs } 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';
const toastStore = useToastStore();
// Props // Props
const props = defineProps({ const props = defineProps({
item: { item: {
type: Object, type: Object,
required: true, required: true
}, },
cateList: {
type: Array,
required: false,
}
}); });
//
const localCateList = ref([...props.cateList]);
//
const selectedCategory = ref('');
// cateList emit
const emit = defineEmits(['update:cateList']);
//
const isWriteVisible = ref(false);
// toggle
const toggleWriteVisible = () => {
isWriteVisible.value = !isWriteVisible.value;
};
//
const addCategory = (data) => {
try {
const lastCategory = localCateList.value.length > 0
? localCateList.value[localCateList.value.length - 1]
: null;
const newValue = lastCategory ? lastCategory.value + 1 : 600101;
axios.post('worddict/insertCategory', {
CMNCODNAM: data
}).then(res => {
if(res.data.data === 1){
toastStore.onToast('카테고리가 추가 등록 되었습니다.', 's');
const newCategory = { label: data, value: newValue };
localCateList.value = [newCategory, ...localCateList.value];
selectedCategory.value = newCategory.value;
//
emit('update:cateList', localCateList.value);
}
}).catch(err => {
console.error('카테고리 추가 중 오류:', err);
});
} catch (err) {
console.error('카테고리 추가 함수 오류:', err);
}
}
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 getProfileImage = (imagePath) => const getProfileImage = (imagePath) =>
imagePath ? `${baseUrl}upload/img/profile/${imagePath}` : '/img/avatars/default-Profile.jpg'; imagePath ? `${baseUrl}upload/img/profile/${imagePath}` : '/img/avatars/default-Profile.jpg';
</script> </script>
<style scoped> <style scoped>
/* 동그란 테두리 설정 */ /* 동그란 테두리 설정 */
.user-avatar { .user-avatar {
border: 3px solid; /* 테두리 */ border: 3px solid; /* 테두리 */
padding: 0.1px; /* 테두리와 이미지 사이의 간격 */ padding: 0.1px; /* 테두리와 이미지 사이의 간격 */
} }
</style>
.edit-btn {
position: absolute;
right: 0.7rem;
top: 1.2rem;
}
</style>

View File

@ -9,6 +9,7 @@
:is-common="true" :is-common="true"
@update:data="selectCategory = $event" @update:data="selectCategory = $event"
@change="onChange" @change="onChange"
:value="formValue"
/> />
</div> </div>
<div class="col-2 btn-margin"> <div class="col-2 btn-margin">
@ -34,11 +35,13 @@
name="word" name="word"
:is-essential="true" :is-essential="true"
:is-alert="wordTitleAlert" :is-alert="wordTitleAlert"
:modelValue="titleValue"
@update:modelValue="wordTitle = $event" @update:modelValue="wordTitle = $event"
/> />
</div> </div>
<div> <div>
<QEditor @update:data="content = $event" @update:imageUrls="imageUrls = $event" :is-alert="wordContentAlert" /> <QEditor @update:data="content = $event" @update:imageUrls="imageUrls = $event" :is-alert="wordContentAlert" />
{{ contentValue }}
<div class="text-end mt-5"> <div class="text-end mt-5">
<button class="btn btn-primary" @click="saveWord"> <button class="btn btn-primary" @click="saveWord">
<i class="bx bx-check"></i> <i class="bx bx-check"></i>
@ -75,17 +78,17 @@ const props = defineProps({
dataList: { dataList: {
type: Array, type: Array,
default: () => [] default: () => []
},
formValue : {
type:[String, Number]
},
titleValue : {
type:String,
},contentValue : {
type:String
} }
}); });
//
// const formattedDataList = computed(() =>
// props.dataList.map(item => ({
// label: item.CMNCODNAM,
// value: item.CMNCODVAL
// }))
// );
// //
const showInput = ref(false); const showInput = ref(false);

View File

@ -48,6 +48,7 @@
v-for="item in wordList" v-for="item in wordList"
:key="item.WRDDICSEQ" :key="item.WRDDICSEQ"
:item="item" :item="item"
:cateList="cateList"
/> />
</ul> </ul>
@ -91,6 +92,7 @@
const { cateList } = commonApi({ const { cateList } = commonApi({
loadCateList: true loadCateList: true
}); });
const selectedCategory = ref(''); const selectedCategory = ref('');
const selectCategory = ref(''); const selectCategory = ref('');
@ -167,8 +169,8 @@
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 };
cateList.value.unshift(newCategory); cateList.value = [newCategory, ...cateList.value];
selectCategory.value = newCategory.CMNCODVAL; selectedCategory.value = newCategory.value;
} }
}) })
} }