diff --git a/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/DTOs/contributiondto/ContributionResultDTO.java b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/DTOs/contributiondto/ContributionResultDTO.java new file mode 100644 index 00000000..540eba94 --- /dev/null +++ b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/DTOs/contributiondto/ContributionResultDTO.java @@ -0,0 +1,11 @@ +package com.Backend.shareNote.domain.Oraganization.DTOs.contributiondto; + +import lombok.Data; + +@Data +public class ContributionResultDTO { + private String userId; + private String nickname; + private Integer quizScore; + private Integer likeScore; +} diff --git a/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/controller/ContributeController.java b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/controller/ContributeController.java new file mode 100644 index 00000000..6bb9e837 --- /dev/null +++ b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/controller/ContributeController.java @@ -0,0 +1,20 @@ +package com.Backend.shareNote.domain.Oraganization.controller; + +import com.Backend.shareNote.domain.Oraganization.service.ContributionService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@Slf4j +@RequiredArgsConstructor +@RequestMapping("/api") +public class ContributeController { + private final ContributionService contributionService; + @GetMapping("/contribute/{organizationId}") + public ResponseEntity getContribution(@PathVariable String organizationId){ + return contributionService.getContribution(organizationId); + + } +} diff --git a/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/entity/Organization.java b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/entity/Organization.java index 1ba9d2f6..02b18860 100644 --- a/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/entity/Organization.java +++ b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/entity/Organization.java @@ -10,10 +10,7 @@ import org.springframework.data.mongodb.core.mapping.Document; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @Document(collection = "organizations") @Builder @@ -115,7 +112,7 @@ public static class Quiz { @Getter @Slf4j public static class LikesInfo { - private Map userLikes = new HashMap<>(); + private Map> userLikes = new HashMap<>(); /** * 좋아요를 추가하거나 취소합니다. @@ -129,46 +126,52 @@ public Boolean addLike(String userUuid, String blockId, String likerUuid) { if(userUuid.equals(likerUuid)) { throw new SelfLikedException("자기 블록에 좋아요를 누를 수 없습니다."); } - return userLikes.computeIfAbsent(userUuid, k -> new UserLike()) - .addBlockLike(blockId, likerUuid); + BlockLike blockLike = new BlockLike(blockId, likerUuid); + userLikes.putIfAbsent(userUuid, new HashSet<>()); + if(userLikes.get(userUuid).contains(blockLike)) { + log.info("이미 좋아요를 누른 상태입니다."); + userLikes.get(userUuid).remove(blockLike); + return false; + }else { + userLikes.get(userUuid).add(blockLike); + return true; + } } - // 필요한 메서드 추가... - } - @Getter - public static class UserLike { - private Map blockLikes = new HashMap<>(); - - public Boolean addBlockLike(String blockId, String likerUuid) { - return blockLikes.computeIfAbsent(blockId, k -> new BlockLike()) - .addLiker(likerUuid); + // 기여도에서 좋아요 개수를 가져오기 위한 메서드 + public int getLikeCount(String userUuid){ + return userLikes.get(userUuid).size(); } // 필요한 메서드 추가... } @Getter public static class BlockLike { - private List likers = new ArrayList<>(); - - public Boolean addLiker(String likerUuid) { - // 좋아요 취소 로직 구현 및 좋아요 여부 확인 - if(likers.contains(likerUuid)){ - likers.remove(likerUuid); - return false; - } - else{ - likers.add(likerUuid); - return true; - } + private String blockId; + private String likerUuid; + public BlockLike(String blockId, String likerUuid) { + this.blockId = blockId; + this.likerUuid = likerUuid; + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BlockLike blockLike = (BlockLike) o; + return Objects.equals(blockId, blockLike.blockId) && Objects.equals(likerUuid, blockLike.likerUuid); } - // 필요한 메서드 추가... + @Override + public int hashCode() { + return Objects.hash(blockId, likerUuid); + } } + public void addPageToNote(String noteId, Page newPage) { for (Note note : this.notes) { if (note.getId().equals(noteId)) { diff --git a/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/service/ContributionService.java b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/service/ContributionService.java new file mode 100644 index 00000000..a2053e13 --- /dev/null +++ b/backend/shareNote/src/main/java/com/Backend/shareNote/domain/Oraganization/service/ContributionService.java @@ -0,0 +1,82 @@ +package com.Backend.shareNote.domain.Oraganization.service; + +import com.Backend.shareNote.domain.Oraganization.DTOs.contributiondto.ContributionResultDTO; +import com.Backend.shareNote.domain.Oraganization.entity.Organization; +import com.Backend.shareNote.domain.Oraganization.repository.OrganizationRepository; +import com.Backend.shareNote.domain.User.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +@RequiredArgsConstructor +public class ContributionService { + private final OrganizationRepository organizationRepository; + + private final UserRepository userRepository; + + public ResponseEntity getContribution(String organizationId) { + try { + // organization 찾기 + Organization organization = organizationRepository.findById(organizationId) + .orElseThrow(() -> new IllegalArgumentException("해당하는 organization이 없습니다.")); + + + // 우선 organization의 멤버들의 우선 quiz 맞춘게 있으면 +1을 하자 + List resultlist = new ArrayList<>(); + + HashMap quizMap = new HashMap<>(); + HashMap likeMap = new HashMap<>(); + + // quizMap 초기화 + organization.getMembers().forEach(member -> { + quizMap.put(member, 0); + }); + + // 노트 조회 하면서 퀴즈의 맞춘 목록을 뒤지면서 quizMap 완성하기 + organization.getNotes().forEach(note -> { + //note의 like 정보를 갖고 있는 맵 + Map> userLikes = note.getLikesInfo().getUserLikes(); + + for (String uuid :note.getLikesInfo().getUserLikes().keySet()) { + likeMap.put(uuid, likeMap.getOrDefault(uuid,0) + userLikes.get(uuid).size() ); + } + + + note.getQuiz().forEach(quiz -> { + for (String key : quiz.getCorrectUser()) { + quizMap.put(key, quizMap.get(key) + 1); + } + // 퀴즈 출제자도 1점 추가 + quizMap.put(quiz.getUserId(), quizMap.get(quiz.getUserId()) + 1); + }); + }); + + organization.getMembers().forEach(member -> { + // 모든 유저에 대해서 닉네임, id, quizScore, (likeScore)를 넣어주자 + ContributionResultDTO contributionResultDTO = new ContributionResultDTO(); + contributionResultDTO.setUserId(member); + + // 닉네임 추가하기 + userRepository.findById(member).ifPresent(user -> { + contributionResultDTO.setNickname(user.getNickname()); + }); + + // quiz 점수 추가 + contributionResultDTO.setQuizScore(quizMap.get(member)); + + // like 점수 추가 (추후에 추가 예정) + contributionResultDTO.setLikeScore(likeMap.getOrDefault(member,0)); + + resultlist.add(contributionResultDTO); + }); + + return ResponseEntity.ok().body(resultlist); + } catch (Exception e) { + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + +} diff --git a/frontend/src/Component/Page/utils/editor/plugin/generateBlockIdPlugin.js b/frontend/src/Component/Page/utils/editor/plugin/generateBlockIdPlugin.js index 0ba4a252..f28450a7 100644 --- a/frontend/src/Component/Page/utils/editor/plugin/generateBlockIdPlugin.js +++ b/frontend/src/Component/Page/utils/editor/plugin/generateBlockIdPlugin.js @@ -1,3 +1,4 @@ +import { localStorageCache } from "prosemirror-image-plugin"; import { Plugin } from "prosemirror-state"; import { v4 as uuidv4 } from "uuid"; @@ -22,7 +23,7 @@ export const generateBlockIdPlugin = (guidGenerator = uuidv4) => { newGuid = guidGenerator(); } while (generatedIds.has(newGuid)); generatedIds.add(newGuid); - tr.setNodeMarkup(pos, undefined, {...node.attrs, 'data-guid': newGuid}); + tr.setNodeMarkup(pos, undefined, {...node.attrs, 'data-guid': newGuid, 'data-writer': localStorage.getItem('userId')}); modified = true; } else { generatedIds.add(currentGuid); @@ -41,7 +42,7 @@ export const generateBlockIdPlugin = (guidGenerator = uuidv4) => { newGuid = guidGenerator(); } while (generatedIds.has(newGuid)); generatedIds.add(newGuid); - tr.setNodeMarkup(pos, undefined, {...node.attrs, guid: newGuid}); + tr.setNodeMarkup(pos, undefined, {...node.attrs, guid: newGuid, writer: localStorage.getItem('userId')}); modified = true; } } else { @@ -53,7 +54,7 @@ export const generateBlockIdPlugin = (guidGenerator = uuidv4) => { newGuid = guidGenerator(); } while (generatedIds.has(newGuid)); generatedIds.add(newGuid); - tr.setNodeMarkup(pos, undefined, {...node.attrs, guid: newGuid}); + tr.setNodeMarkup(pos, undefined, {...node.attrs, guid: newGuid, writer: localStorage.getItem('userId')}); modified = true; } else { generatedIds.add(currentGuid); diff --git a/nodejs/server.js b/nodejs/server.js index f83b0766..60d8fe16 100644 --- a/nodejs/server.js +++ b/nodejs/server.js @@ -24,8 +24,8 @@ const databaseName = 'shareDB'; function createConnectionString(databaseName) { logger.info(`@@@@@@@@@@@mongodb://root:1234@localhost:27017/${databaseName}?authSource=admin`); - return `mongodb://root:1234@localhost:27017/${databaseName}?authSource=admin`; - //return `mongodb://root:1234@mongodbService:27017/${databaseName}?authSource=admin`; + //return `mongodb://root:1234@localhost:27017/${databaseName}?authSource=admin`; + return `mongodb://root:1234@mongodbService:27017/${databaseName}?authSource=admin`; } const server = http.createServer((req, res) => {