
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
2024-11-19
2024-11-19
<template>
<div class="title-box flex justify-between mb40">
<p class="title">단어장 등록</p>
</div>
<div class="title2 gray flex mb40">{{ titleMessage }}</div>
<div class="board-wrap">
<div class="flex align-center mb20">
<div class="flex align-center">
<label for="" class="title2">교재</label>
<select name="" id="" v-model="selectedBookId" @change="fetchUnits" class="mr10">
<option value="" disabled>교재를 선택하세요</option>
<option v-for="book in books" :key="book.book_id" :value="book.book_id">
{{ book.book_nm }}
</option>
</select>
<select name="" id="" v-model="selectedUnitId" @change="fetchTexts" class="mr10">
<option value="" disabled>단원을 선택하세요</option>
<option v-for="unit in units" :key="unit.unitId" :value="unit.unitId">
{{ unit.unitName }}
</option>
</select>
<select v-model="selectedTextId" class="mr10 data-wrap">
<option value="" disabled>지문을 선택하세요</option>
<option v-for="text in texts" :key="text.textId" :value="text.textId">
{{ text.textTtl }}
</option>
</select>
</div>
</div>
<div class="flex align-center mb20">
<label for="" class="title2">단어장 타입</label>
<select v-model="selectedWdBookTypeId" class="mr10 data-wrap">
<option value="1">단어장 (일반)</option>
<option value="2">단어장 (스피킹)</option>
<option value="3">단어장 (숏폼)</option>
<option value="4">단어장 (카드 뒤집기)</option>
<option value="5">단어장 (카드 맞추기)</option>
</select>
</div>
<div class="flex align-center">
<label for="" class="title2">단어 목록</label>
<div class="flex-column" style="gap: 10px;">
<div class="flex align-center" style="gap: 10px;">
<input v-model="newWord.eng" type="text" class="data-wrap" placeholder="영어">
<input v-model="newWord.kor" type="text" class="data-wrap" placeholder="한글">
<input type="file" ref="fileInput" @change="handleFileUpload" multiple />
<button type="button" @click="addWord">
<img src="../../../resources/img/btn39_120t_normal.png" alt="">
</button>
</div>
<!-- 여기에 단어장에 소속될 단어들 태그 형태 리스트 -->
<div v-for="(word, index) in words" :key="index" class="word-item flex align-center" style="gap: 10px;">
<span>{{ word.eng }} / {{ word.kor }}</span>
<div v-for="(data, index2) in word.file" :key="index2">
/ {{ data.fileNm }}
</div>
<button type="button" @click="removeWord(index)">삭제</button>
</div>
</div>
</div>
</div>
<div class="flex justify-between mt50">
<button type="button" title="목록" class="new-btn" @click="goToPage('VocaList')">
목록
</button>
<div class="flex">
<button type="button" title="취소" class="new-btn mr10" @click="cancelAction">
취소
</button>
<button type="button" title="등록" class="new-btn" @click="registerWordBook">
등록
</button>
</div>
</div>
</template>
<script>
import SvgIcon from '@jamescoyle/vue-icon';
import axios from "axios";
export default {
data() {
return {
selectedBookId: null, // 추가될 단어장의 소속 책
selectedUnitId: null, // 추가될 단어장의 소속 단원
bookName: '', // 책 이름
unitName: '', // 단원 이름
titleMessage: '', // 등록 경로 메시지
texts: [], // 지문 목록
selectedTextId: null, // 선택된 지문 ID
selectedWdBookTypeId: '1', // 선택된 단어장 타입 ID
newWord: { eng: '', kor: '', fileMngId: null }, // 입력된 새 단어
words: [], // 단어 목록
books: [],
units: [],
existingWords: [], // 기존 단어 목록 저장
userId: "USID_000000000000004",
file: '',
selectedFiles: [],
}
},
methods: {
async handleFileUpload(e) {
const files = e.target.files;
if (files.length > 0) {
const fileMngId = await this.uploadFiles(files);
this.newWord.fileMngId = fileMngId; // 파일 매니지 ID 저장
}
},
// 교재 정보 가져오기
fetchBooks() {
this.selectedUnitId = '';
this.selectedTextId = '';
axios({
url: "/book/findAll.json",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
})
.then(response => {
console.log(response.data)
this.books = response.data;
this.selectedTextId = '';
})
.catch(error => {
console.error("fetchBooks - error: ", error);
alert("교재 목록을 불러오는 중 오류가 발생했습니다.");
});
},
// 단원 정보 가져오기
fetchUnits() {
if (!this.selectedBookId) return;
axios({
url: "/unit/unitList.json",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: {
"bookId": this.selectedBookId
},
})
.then(response => {
this.units = response.data;
this.selectedTextId = '';
})
.catch(error => {
console.error("fetchUnits - error: ", error);
alert("단원 목록을 불러오는 중 오류가 발생했습니다.");
});
},
// 책과 단원 이름을 가져오는 메서드
fetchBookAndUnitNames() {
// 책 이름 가져오기
axios.post('/book/findAll.json')
.then(response => {
const book = response.data.find(book => book.book_id === this.selectedBookId);
this.books = response.data;
if (book) {
this.bookName = book.book_nm;
this.updateTitleMessage(); // 책 이름을 가져온 후에 제목 업데이트
}
})
.catch(error => {
console.error("책 이름 가져오기 실패: ", error);
});
// 단원 이름 가져오기
axios.post('/unit/unitList.json', { bookId: this.selectedBookId })
.then(response => {
const unit = response.data.find(unit => unit.unitId === this.selectedUnitId);
this.units = response.data;
if (unit) {
this.unitName = unit.unitName;
this.updateTitleMessage(); // 단원 이름을 가져온 후에 제목 업데이트
}
})
.catch(error => {
console.error("단원 이름 가져오기 실패: ", error);
});
},
// 등록 경로 메시지를 업데이트하는 메서드
updateTitleMessage() {
this.titleMessage = `[${this.bookName}]책 > [${this.unitName}]단원`;
},
// 지문 목록을 가져오는 메서드
fetchTexts() {
axios({
url: "/text/textSearch.json",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: {
"unitId": this.selectedUnitId
},
})
.then(response => {
this.texts = response.data.list;
})
.catch(error => {
console.error("fetchTexts - error: ", error);
alert("지문 목록을 불러오는 중 오류가 발생했습니다.");
});
},
async addWord() { // 단어 추가
if (this.newWord.eng && this.newWord.kor) {
const newWordWithFile = {
...this.newWord,
file: [] // 파일 정보 저장을 위한 배열 추가
};
// 파일 매니지 ID가 있을 경우 파일 정보를 추가
if (newWordWithFile.fileMngId) {
const fileInfo = await this.findFile(newWordWithFile.fileMngId);
newWordWithFile.file = fileInfo; // 파일 정보 추가
}
this.words.push(newWordWithFile); // 단어 추가
// 초기화
this.newWord.eng = '';
this.newWord.kor = '';
this.newWord.fileMngId = null; // 파일 매니지 ID 초기화
} else {
console.log("단어 입력이 비어 있음");
}
},
removeWord(index) { // 단어 삭제
this.words.splice(index, 1);
},
goToPage(page) {
this.$router.push({ name: page });
},
cancelAction() {
this.$router.go(-1);
},
// 기존 단어 조회 메서드
fetchExistingWords(wdBookId) {
return axios.post('/word/getWordsByBookId.json', { wdBookId: wdBookId })
.then(response => {
return response.data.words || [];
})
.catch(error => {
console.error('기존 단어 목록 가져오기 실패:', error);
return [];
});
},
// 파일 업로드 메서드
async uploadFiles(files) {
if (!files || files.length === 0) {
return null;
}
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append("files", files[i]);
}
try {
const response = await axios.post("http://165.229.169.113:9080/file/upload.json", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
return response.data.fileMngId; // 파일 매니지 ID 반환
} catch (error) {
console.error("파일 업로드 오류:", error);
throw new Error("파일 업로드에 실패했습니다.");
}
},
// 업로드한 파일 정보 가져오기
async findFile(fileMngId) {
const vm = this;
try {
const response = await axios({
url: "/file/find.json",
method: "post",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
data: {
file_mng_id: fileMngId,
},
});
console.log("fileInfo - response : ", response.data.list);
return response.data.list; // 파일 정보를 반환
} catch (error) {
console.log("result - error : ", error);
return []; // 오류 발생 시 빈 배열 반환
}
},
async registerWordBook() {
const vm = this;
try {
const response = await axios.post('/wordbook/insert.json', {
wdBookTypeId: vm.selectedWdBookTypeId,
textId: vm.selectedTextId,
userId: vm.userId,
bookId: vm.selectedBookId,
unitId: vm.selectedUnitId
});
const wdBookId = response.data.wdBookId;
// 기존 단어 목록 조회
const existingWords = await vm.fetchExistingWords(wdBookId);
vm.existingWords = existingWords;
const existingWordNames = existingWords.map(word => word.wdNm);
const wordsToInsert = [];
const wordsToUpdate = [];
const wordsToDelete = [];
// 새로 추가된 단어와 기존 단어 비교
vm.words.forEach(word => {
if (existingWordNames.includes(word.eng)) {
wordsToUpdate.push(word);
} else {
wordsToInsert.push(word);
}
});
// 삭제된 단어 목록 찾기
existingWords.forEach(word => {
if (!vm.words.find(newWord => newWord.eng === word.wdNm)) {
wordsToDelete.push(word);
}
});
// 단어 삽입
for (const word of wordsToInsert) {
await axios.post('/word/insert.json', {
wdBookId: wdBookId,
wdNm: word.eng,
wdMnng: word.kor,
fileMngId: word.fileMngId,
});
}
// 단어 업데이트
for (const word of wordsToUpdate) {
await axios.post('/word/update.json', {
wdBookId: wdBookId,
wdNm: word.eng,
wdMnng: word.kor,
fileMngId: word.fileMngId,
});
}
// 단어 삭제
for (const word of wordsToDelete) {
const wordToDelete = existingWords.find(existingWord => existingWord.wdNm === word.wdNm);
if (wordToDelete) {
await axios.post('/word/delete.json', {
wdBookId: wdBookId,
wdId: wordToDelete.wdId
});
}
}
alert('단어장이 성공적으로 등록되었습니다.');
vm.goToPage('VocaList');
} catch (error) {
console.error('단어장 등록 중 오류 발생:', error);
alert('단어장 등록에 실패했습니다.');
}
}
},
watch: {
// 데이터 변경 시 등록 경로 메시지 업데이트
selectedBookId() {
this.fetchBookAndUnitNames();
},
selectedUnitId() {
this.fetchBookAndUnitNames();
}
},
computed: {
},
components: {
SvgIcon
},
mounted() {
console.log('VocaInsert mounted');
// 쿼리 전달 받기
this.selectedBookId = this.$route.query.selectedBookId || null;
this.selectedUnitId = this.$route.query.selectedUnitId || null;
this.fetchTexts();
this.fetchBookAndUnitNames();
}
}
</script>