store/modules/mylogs.js
// src/store/modules/mylogs.js
import { v4 as uuidv4 } from 'uuid';
import { db, doc, collection, getDoc, getDocs, setDoc, addDoc,updateDoc, deleteDoc, arrayUnion, increment, where } from "@/firebase";
import { query, orderBy } from "@/firebase";
const state = {
loading: false,
error: null,
mylog: null,
mylogs: [],
userMylogs: [], // 회원의 마이로그
isSubscribed: false, // 구독 여부 - 마이로그 상세 보기에서 사용
subscriptionId: '', // 구독 등록 Id - 구독정보 삭제에 사용
subscriptions: [], // 구독 목록
subscribedMylogs: [], // 구독 마이로그 목록
comments: [], // 댓글 목록 저장
filteredMylogs: [], // 검색된 게시물 목록
readers: [], // 독자들
};
const mutations = {
setLoading(state, loading) {
state.loading = loading;
},
setError(state, error) {
state.error = error;
},
setMylogs(state, mylogs) {
state.mylogs = mylogs;
},
setMylog(state, mylog) {
state.mylog = mylog;
},
setUserMylogs(state, mylogs) {
state.userMylogs = mylogs;
},
setSubscribed(state, subscribed) { // 구독 여부
state.isSubscribed = subscribed;
},
setSubscriptionId(state, subscriptionId) { // 구독 Id
state.subscriptionId = subscriptionId;
},
setSubscriptions(state, subscriptions) { // 구독 목록
state.subscriptions = subscriptions;
},
setSubscribedMylogs(state, subscribedMylogs) { // 구독 마이로그 목록
state.subscribedMylogs = subscribedMylogs;
},
setComments(state, comments) { // 현재 댓글
state.comments = comments;
},
addComment(state, comment) { // 댓글 추가
state.comments.push(comment);
},
addReply(state, { commentId, reply }) { // 댓글에 대한 답글 추가
const comment = state.comments.find(c => c.id === commentId);
if (comment) {
if (!comment.replies) {
comment.replies = [];
}
comment.replies.push(reply);
}
},
setFilteredMylogs(state, filteredMylogs) { // 마이로그 찾기
state.filteredMylogs = filteredMylogs;
},
setReaders(state, readers) { // 독자들
state.readers = readers;
},
};
const actions = {
// 전체 마이로그를 작성일 역순으로 로드한다.
async fetchMylogs({ commit }) {
commit('setLoading', true);
try {
const mylogs = [];
const mylogsRef = query(collection(db, "mylogs"), orderBy("createdAt", "desc"));
const querySnapshot = await getDocs(mylogsRef);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
mylogs.push({ id: doc.id, ...doc.data() });
});
// state에 저장한다.
commit('setMylogs', mylogs);
} catch (error) {
console.log("error: ", error);
commit('setError', error);
} finally {
commit('setLoading', false);
}
},
// 전체 마이로그를 작성일 순으로 로드한다.
async fetchMylogsAsc({ commit }) {
commit('setLoading', true);
try {
const mylogs = [];
const mylogsRef = query(collection(db, "mylogs"), orderBy("createdAt", "asc"));
const querySnapshot = await getDocs(mylogsRef);
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
mylogs.push({ id: doc.id, ...doc.data() });
});
// state에 저장한다.
commit('setMylogs', mylogs);
} catch (error) {
commit('setError', error);
} finally {
commit('setLoading', false);
}
},
// mylogId로 마이로그를 로드한다.
async fetchMylog({ commit }, mylogId) {
//console.log('mylogId:', mylogId);
commit('setLoading', true);
try {
const docRef = doc(db, "mylogs", mylogId); // Reference to the specific article document
const docSnap = await getDoc(docRef); // Fetch the document snapshot
if (docSnap.exists()) {
const mylog = docSnap.data(); // Set article data
commit('setMylog', mylog);
} else {
console.error("mylog가 없습니다.");
}
} catch (error) {
commit('setError', error);
} finally {
commit('setLoading', false);
}
},
// 현재 사용자가 작성한 게시물 불러오기 - 최신순 정열
async fetchUserMylogs({ commit }, userId) {
commit('setLoading', true);
if (userId) {
try {
const q = query(collection(db, "mylogs"), where("userId", "==", userId), orderBy("createdAt", "desc"));
const querySnapshot = await getDocs(q);
const mylogs = [];
querySnapshot.forEach((doc) => {
mylogs.push({ id: doc.id, ...doc.data() });
});
commit('setUserMylogs', mylogs); // 상태에 저장
} catch (error) {
console.error("본인 글 가져오기 실패:", error);
commit('setError', error);
}
}
commit('setLoading', false);
},
// 현재 사용자가 작성한 게시물 불러오기 - 오래된순 정열
async fetchUserMylogsOrderByDateAsc({ commit }, userId) {
commit('setLoading', true);
if (userId) {
try {
const q = query(collection(db, "mylogs"), where("userId", "==", userId), orderBy("createdAt", "asc"));
const querySnapshot = await getDocs(q);
const mylogs = [];
querySnapshot.forEach((doc) => {
mylogs.push({ id: doc.id, ...doc.data() });
});
commit('setUserMylogs', mylogs); // 상태에 저장
} catch (error) {
console.error("본인 글 가져오기 실패:", error);
commit('setError', error);
}
}
commit('setLoading', false);
},
// 현재 사용자가 작성한 게시물 불러오기 - 조회수 역순 정열
async fetchUserMylogsOrderByViews({ commit }, userId) {
commit('setLoading', true);
if (userId) {
try {
const q = query(collection(db, "mylogs"), where("userId", "==", userId), orderBy("views", "desc"));
const querySnapshot = await getDocs(q);
const mylogs = [];
querySnapshot.forEach((doc) => {
mylogs.push({ id: doc.id, ...doc.data() });
});
commit('setUserMylogs', mylogs); // 상태에 저장
} catch (error) {
console.error("본인 글 가져오기 실패:", error);
commit('setError', error);
}
}
commit('setLoading', false);
},
// 현재 사용자가 작성한 게시물 불러오기 - 조회수 역순 정열
async fetchUserMylogsOrderByCreated({ commit }, userId) {
commit('setLoading', true);
if (userId) {
try {
const q = query(collection(db, "mylogs"), where("userId", "==", userId), orderBy("createdAt", "asc"));
const querySnapshot = await getDocs(q);
const mylogs = [];
querySnapshot.forEach((doc) => {
mylogs.push({ id: doc.id, ...doc.data() });
});
commit('setUserMylogs', mylogs); // 상태에 저장
} catch (error) {
console.error("본인 글 가져오기 실패:", error);
commit('setError', error);
}
}
commit('setLoading', false);
},
// 조회 기록 업데이트 함수
async updateViewCount({ commit }, mylogId, userId = null) {
let viewId;
let viewedToday;
// 비회원일 경우 로컬 스토리지 또는 쿠키를 사용하여 고유 ID 생성
if (!userId) {
viewId = localStorage.getItem('anonymousUserId');
if (!viewId) {
viewId = uuidv4();
localStorage.setItem('anonymousUserId', viewId);
}
} else {
viewId = userId; // 회원일 경우 사용자 ID
}
try {
const today = new Date().toISOString().split('T')[0];
const viewDocRef = doc(db, 'views', mylogId, 'users', viewId);
// Firestore에서 해당 사용자의 조회 기록을 가져옵니다.
const viewDoc = await getDoc(viewDocRef);
if (viewDoc.exists()) {
// 오늘 조회 기록이 있는지 확인
const lastViewed = viewDoc.data().lastViewed;
viewedToday = lastViewed.some(view => view === today);
}
// 조회한 내역이 없으면 조회수 추가
if (!viewedToday) {
// Firestore의 lastViewed 배열에 조회 시간을 추가
await setDoc(viewDocRef, {
lastViewed: arrayUnion(today) // 배열에 서버 시간을 추가
}, { merge: true });
// mylog 조회수 증가
const mylogRef = doc(db, "mylogs", mylogId);
try {
// 조회수 1 증가 또는 필드가 없을 때 1로 설정
await updateDoc(mylogRef, {
views: increment(1)
});
} catch (error) {
alert(error.message);
}
}
} catch (error) {
alert(error.message);
}
},
// 작성한 마이로그를 firestore에 저장한다.
async saveMylog({ commit, dispatch }, { title, content, userId, userName, createdAt }) {
commit('setLoading', true);
try {
const mylog = await addDoc(collection(db, "mylogs"), {
title: title,
content: content,
userId: userId,
userName: userName,
createdAt: createdAt
});
dispatch('fetchMylogs'); // 새 마이로그을 저장한 후 전체 마이로그를 새로 읽는다.
} catch (error) {
alert(error.message);
} finally {
commit('setLoading', false);
}
},
// 게시물 수정 액션
async updateMylog({ commit, dispatch }, { mylogId, updatedData }) {
try {
commit('setLoading', true);
const mylogRef = doc(db, "mylogs", mylogId);
await updateDoc(mylogRef, {
title: updatedData.title,
content: updatedData.content,
updatedAt: new Date(), // 수정한 시간 기록
});
commit('setLoading', false);
alert("마이로그를 수정하였습니다.");
// 마이로그 수정 후 전체 다시 로드하록 한다.
dispatch('fetchMylogs');
} catch (error) {
alert("마이로그 수정 실패 : " + error.message);
}
},
// comments 가져오기
async fetchComments({ commit, dispatch }, mylogId) {
try {
const q = query(collection(db, "mylogs", mylogId, "comments"), orderBy("createdAt", "asc"));
const querySnapshot = await getDocs(q);
const comments = [];
querySnapshot.forEach((doc) => {
comments.push({ id: doc.id, ...doc.data(), replies: [] });
// 댓글에 대한 답글 로드
dispatch('fetchReplies', { mylogId, commentId: doc.id });
});
commit('setComments', comments); // 댓글을 상태에 저장
} catch (error) {
commit("setError", error);
console.error("댓글 가져오기 실패:", error);
}
},
// comments 추가 하기
async addComment({ commit, dispatch }, { mylogId, content, userName, userId }) {
try {
// db에 댓글 저장
const commentRef = await addDoc(collection(db, "mylogs", mylogId, "comments"), {
content: content, userName: userName, userId: userId, createdAt: new Date(),
});
// 저장한 댓글을 상태에 로드된 댓글에 추가
const newComment = { id: commentRef.id, content, userName, userId, createdAt: new Date() };
commit('addComment', newComment); // 새 댓글을 상태에 추가
// mylog의 댓글수 증가
const mylogRef = doc(db, "mylogs", mylogId);
try {
// 조회수 1 증가 또는 필드가 없을 때 1로 설정
await updateDoc(mylogRef, {
commentCount: increment(1)
});
} catch (error) {
commit('setError', error);
}
dispatch('fetchMylogs');
} catch (error) {
commit("setError", error);
console.error("댓글 추가 실패:", error);
}
},
// 댓글 삭제
async deleteComment({ commit, dispatch }, { mylogId, commentId }) {
const commentRef = doc(db, "mylogs", mylogId, "comments", commentId);
try {
await deleteDoc(commentRef);
dispatch('fetchComments', mylogId); // 댓글 다시 로그
// mylog의 댓글수 증가
const mylogRef = doc(db, "mylogs", mylogId);
try {
// 조회수 1 증가 또는 필드가 없을 때 1로 설정
await updateDoc(mylogRef, {
commentCount: increment(-1)
});
} catch (error) {
commit('setError', error);
}
dispatch('fetchMylogs');
//this.comments = this.comments.filter(c => c.id !== commentId);
console.log("댓글이 삭제되었습니다.");
} catch (error) {
commit("setError", error);
console.error("댓글 삭제 실패:", error);
}
},
// 댓글에 답글 추가
async addReply({ commit }, { mylogId, commentId, content, userName, userId }) {
try {
// db에 답글 저장
const replyRef = await addDoc(collection(db, "mylogs", mylogId, "comments", commentId, "replies"), {
content: content, userName: userName, userId: userId, createdAt: new Date()
});
// 로드된 댓글에 답글 저장
const newReply = { id: replyRef.id, content, userName, userId, createdAt: new Date() };
commit('addReply', { commentId, reply: newReply });
} catch (error) {
commit("setError", error);
console.error("답글 추가 실패:", error);
}
},
// 답글 삭제
async deleteReply({ commit, dispatch }, { mylogId, commentId, replyId }) {
const replyRef = doc(db, "mylogs", mylogId, "comments", commentId, "replies", replyId);
try {
await deleteDoc(replyRef);
dispatch('fetchComments', mylogId); // 댓글 다시 로그
console.log("답글이 삭제되었습니다.");
} catch (error) {
commit("setError", error);
console.error("답글 삭제 실패:", error);
}
},
// 특정 댓글의 답글 불러오기
async fetchReplies({ commit }, { mylogId, commentId }) {
try {
const q = query(collection(db, "mylogs", mylogId, "comments", commentId, "replies"), orderBy("createdAt", "asc"));
const querySnapshot = await getDocs(q);
const replies = [];
querySnapshot.forEach((doc) => {
replies.push({ id: doc.id, ...doc.data() });
});
replies.forEach(reply => {
commit('addReply', { commentId, reply });
});
} catch (error) {
commit("setError", error);
console.error("답글 불러오기 실패:", error);
}
},
// 구독 여부 확인
async checkSubscription({ commit }, { userId, authorId }) {
commit('setLoading', true);
const q = query(
collection(db, "subscriptions"),
where("userId", "==", userId),
where("authorId", "==", authorId)
);
const querySnapshot = await getDocs(q);
if (!querySnapshot.empty) {
commit("setSubscribed", true);
commit("setSubscriptionId", querySnapshot.docs[0].id); // Get the Firestore document ID for the subscription
} else {
commit("setSubscribed", false);
commit("setSubscriptionId", '');
}
commit('setLoading', false);
},
// 구독
async subscribeToUser({ commit, dispatch }, {userId, authorId}) {
//console.log('userId: ',userId )
//console.log('authorId: ',authorId )
commit('setLoading', true);
try {
const subscriptionRef = collection(db, "subscriptions");
await addDoc(subscriptionRef, {
userId: userId,
authorId: authorId,
createdAt: new Date(),
});
dispatch("fetchUserSubscriptions", userId);
} catch (error) {
commit("setError", error);
console.error("Error subscribing:", error);
}
commit('setLoading', false);
},
// 구독 해지
async unsubscribeFromUser({ commit, dispatch }, {userId, subscriptionId}) {
commit('setLoading', true);
try {
const subscriptionDocRef = doc(db, "subscriptions", subscriptionId);
await deleteDoc(subscriptionDocRef);
dispatch("fetchUserSubscriptions", userId);
} catch (error) {
//commit("setError", error);
alert("Error unsubscribing : ", error.message);
}
commit('setLoading', false);
},
// user에 대한 구독 로드
async fetchUserSubscriptions({ commit }, userId) {
const subscriptionRef = collection(db, "subscriptions");
const q = query(subscriptionRef, where("userId", "==", userId));
const querySnapshot = await getDocs(q);
const subscriptions = [];
querySnapshot.forEach((doc) => {
subscriptions.push(doc.data());
});
commit("setSubscriptions", subscriptions);
},
// 구독 중인 마이로그 로드
async fetchSubscribedMylogs({ commit }, userId) {
commit('setLoading', true);
// 구독 목록
const authodIds = [];
const q = query(collection(db, "subscriptions"), where("userId", "==", userId));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
authodIds.push(doc.data().authorId);
});
// 구독 마이로그 목록
if(authodIds.length>0) {
let subscribedMylogs = [];
const mylogQ = query(collection(db, "mylogs"), where("userId", "in", authodIds));
const mylogsSnapshot = await getDocs(mylogQ);
subscribedMylogs = mylogsSnapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
// 구독 마이로그 목록을 상태에 저장
commit("setSubscribedMylogs", subscribedMylogs);
}
commit('setLoading', false);
},
// Firestore에서 게시물 검색
async searchMylogs({ commit, getters }, searchTerm ) {
// 검색어를 소문자로
const searchTermLower = searchTerm.toLowerCase();
let filteredMylogs = [];
// 검색된 결과 필터링
filteredMylogs = getters.mylogs.filter((mylog) => {
// title 또는 content에 검색어가 포함된 게시물 검색
return (
mylog.title.toLowerCase().includes(searchTermLower) ||
mylog.content.toLowerCase().includes(searchTermLower)
);
});
commit('setFilteredMylogs', filteredMylogs); // 검색 결과를 상태에 저장
},
// -- 독자 ------
// 1. subscriptions 컬렉션의 문서에서 authorId가 나의 id인 userId 배열을 구한다.
// 2. userId의 배열에 포함된 userId를 가진 모든 회원의 정보를 얻어 목록으로 나타낸다.
async fetchReaders({ commit }, userId) {
commit('setLoading', true);
// 구독 목록
const userIds = [];
const q = query(collection(db, "subscriptions"), where("authorId", "==", userId));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
userIds.push(doc.data().userId);
});
if(userIds.length> 0)
{
//독자들
let readers = [];
for (const userId of userIds) {
const userDocRef = doc(db, "users", userId);
const userDoc = await getDoc(userDocRef);
if (userDoc.exists()) {
readers.push({id: userId, ...userDoc.data()});
//console.log(`${userId} =>`, userDoc.data());
} else {
console.log(`No such user with ID: ${userId}`);
}
}
// 구독 마이로그 목록을 상태에 저장
commit("setReaders", readers);
commit('setLoading', false);
}
},
};
const getters = {
error: state => state.error,
loading: state => state.loading,
mylog: state => state.mylog,
mylogs: state => state.mylogs,
userMylogs: state => state.userMylogs,
isSubscribed: state => state.isSubscribed, // 구독 여부 - 마이로그 상세 보기에서 사용
subscriptionId: state => state.subscriptionId, // 구독 등록 Id - 구독정보 삭제에 사용
subscriptions : state => state.subscriptions, // 구독 목록
subscribedMylogs: state => state.subscribedMylogs, // 구독 마이로그 목록
comments: state => state.comments,
filteredMylogs: state => state.filteredMylogs, // 검색된 게시물 목록
readers: state => state.readers, // 독자들
};
export default {
namespaced: true,
state,
mutations,
actions,
getters
};