mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-07 16:36:24 +00:00
Compare commits
No commits in common. "55159092063202e4e5028a78646976753757639c" and "db16306b064a7c1c0e6d7858b05d4d9283395589" have entirely different histories.
5515909206
...
db16306b06
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -125,12 +125,6 @@ public class MinutesDTO {
|
||||
* 참석자 수
|
||||
*/
|
||||
private final Integer participantCount;
|
||||
|
||||
/**
|
||||
* 검증완료율 (작성중 상태일 때만 유효)
|
||||
* 0-100 사이의 값
|
||||
*/
|
||||
private final Integer verificationRate;
|
||||
|
||||
/**
|
||||
* 회의 정보
|
||||
|
||||
@ -240,21 +240,20 @@ public class MinutesService implements
|
||||
|
||||
/**
|
||||
* 사용자 ID로 회의록 목록 조회 (페이징)
|
||||
* 사용자가 생성했거나 참여한 회의의 회의록을 모두 조회
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
public Page<MinutesDTO> getMinutesListByUserId(String userId, Pageable pageable) {
|
||||
log.debug("Getting minutes list by userId: {}", userId);
|
||||
|
||||
// 사용자가 생성했거나 참여한 회의의 회의록 조회
|
||||
List<Minutes> minutesList = minutesReader.findByParticipantUserId(userId);
|
||||
// 여기서는 임시로 작성자 기준으로 조회 (실제로는 참석자나 권한 기반으로 조회해야 함)
|
||||
List<Minutes> minutesList = minutesReader.findByCreatedBy(userId);
|
||||
|
||||
// Minutes를 MinutesDTO로 변환
|
||||
List<MinutesDTO> minutesDTOList = minutesList.stream()
|
||||
.map(this::convertToMinutesDTO)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 페이징 처리
|
||||
// 페이징 처리 (임시로 전체 목록 반환)
|
||||
int start = (int) pageable.getOffset();
|
||||
int end = Math.min((start + pageable.getPageSize()), minutesDTOList.size());
|
||||
List<MinutesDTO> pageContent = minutesDTOList.subList(start, end);
|
||||
@ -372,15 +371,6 @@ public class MinutesService implements
|
||||
log.warn("섹션 정보 변환 실패 - minutesId: {}", minutes.getMinutesId(), e);
|
||||
}
|
||||
|
||||
// 검증완료율 계산 (작성중 상태일 때만)
|
||||
Integer verificationRate = null;
|
||||
if ("DRAFT".equals(minutes.getStatus()) && sectionDTOs != null && !sectionDTOs.isEmpty()) {
|
||||
long verifiedCount = sectionDTOs.stream()
|
||||
.filter(section -> Boolean.TRUE.equals(section.getIsVerified()))
|
||||
.count();
|
||||
verificationRate = (int) ((verifiedCount * 100) / sectionDTOs.size());
|
||||
}
|
||||
|
||||
// decisions 값 로깅
|
||||
log.info("Minutes decisions 값 확인 - minutesId: {}, decisions: {}",
|
||||
minutes.getMinutesId(), minutes.getDecisions());
|
||||
@ -399,7 +389,6 @@ public class MinutesService implements
|
||||
.todoCount(todoCount)
|
||||
.completedTodoCount(completedTodoCount)
|
||||
.participantCount(participantCount)
|
||||
.verificationRate(verificationRate)
|
||||
.memo("") // 메모 필드는 추후 구현
|
||||
.sections(sectionDTOs) // 섹션 정보 추가
|
||||
.decisions(minutes.getDecisions()) // decisions 필드 추가
|
||||
|
||||
@ -56,13 +56,4 @@ public interface MinutesReader {
|
||||
* @return AI 통합 회의록
|
||||
*/
|
||||
Optional<Minutes> findConsolidatedMinutesByMeetingId(String meetingId);
|
||||
|
||||
/**
|
||||
* 사용자가 참여한 회의의 회의록 목록 조회
|
||||
* 사용자가 생성했거나 참여한 회의의 회의록을 모두 조회
|
||||
*
|
||||
* @param userId 사용자 ID
|
||||
* @return 회의록 목록
|
||||
*/
|
||||
List<Minutes> findByParticipantUserId(String userId);
|
||||
}
|
||||
|
||||
@ -110,13 +110,12 @@ public class MinutesController {
|
||||
|
||||
// DTO를 Response 형식으로 변환
|
||||
List<MinutesListResponse.MinutesItem> minutesList = minutesPage.getContent().stream()
|
||||
.map(dto -> convertToMinutesItem(dto, userId))
|
||||
.map(this::convertToMinutesItem)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 필터링 적용 (상태별, 참여 유형별, 검색어)
|
||||
// 필터링 적용 (상태별)
|
||||
List<MinutesListResponse.MinutesItem> filteredMinutes = minutesList.stream()
|
||||
.filter(item -> filterByStatus(item, status))
|
||||
.filter(item -> filterByParticipationType(item, participationType))
|
||||
.filter(item -> filterBySearch(item, search))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@ -490,21 +489,8 @@ public class MinutesController {
|
||||
*/
|
||||
private MinutesListResponse.Statistics calculateRealStatistics(String userId, String participationType) {
|
||||
try {
|
||||
// 전체 회의록 조회 (참여자 기준)
|
||||
List<MinutesDTO> allMinutes = minutesService.getMinutesListByUserId(userId, PageRequest.of(0, Integer.MAX_VALUE)).getContent();
|
||||
|
||||
// 참여 유형 필터링
|
||||
if (participationType != null && !participationType.isEmpty()) {
|
||||
if ("created".equals(participationType)) {
|
||||
allMinutes = allMinutes.stream()
|
||||
.filter(m -> userId.equals(m.getCreatedBy()))
|
||||
.collect(Collectors.toList());
|
||||
} else if ("attended".equals(participationType)) {
|
||||
allMinutes = allMinutes.stream()
|
||||
.filter(m -> !userId.equals(m.getCreatedBy()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
// 전체 회의록 조회 (작성자 기준)
|
||||
List<Minutes> allMinutes = minutesService.getMinutesByCreator(userId);
|
||||
|
||||
long totalCount = allMinutes.size();
|
||||
long draftCount = allMinutes.stream()
|
||||
@ -529,17 +515,10 @@ public class MinutesController {
|
||||
}
|
||||
}
|
||||
|
||||
private MinutesListResponse.MinutesItem convertToMinutesItem(MinutesDTO minutesDTO, String userId) {
|
||||
// 검증완료율 계산 (작성중 상태일 때는 verificationRate 사용, 확정완료시 100%)
|
||||
int completionRate;
|
||||
if ("DRAFT".equals(minutesDTO.getStatus()) && minutesDTO.getVerificationRate() != null) {
|
||||
completionRate = minutesDTO.getVerificationRate();
|
||||
} else if ("FINALIZED".equals(minutesDTO.getStatus())) {
|
||||
completionRate = 100;
|
||||
} else {
|
||||
// 기본값 0
|
||||
completionRate = 0;
|
||||
}
|
||||
private MinutesListResponse.MinutesItem convertToMinutesItem(MinutesDTO minutesDTO) {
|
||||
// 완료율 계산
|
||||
int completionRate = minutesDTO.getTodoCount() > 0 ?
|
||||
(minutesDTO.getCompletedTodoCount() * 100) / minutesDTO.getTodoCount() : 100;
|
||||
|
||||
return MinutesListResponse.MinutesItem.builder()
|
||||
.minutesId(minutesDTO.getMinutesId())
|
||||
@ -556,7 +535,7 @@ public class MinutesController {
|
||||
.todoCount(minutesDTO.getTodoCount())
|
||||
.completedTodoCount(minutesDTO.getCompletedTodoCount())
|
||||
.completionRate(completionRate)
|
||||
.isCreatedByUser(minutesDTO.getCreatedBy().equals(userId)) // 현재 사용자가 생성자인지 확인
|
||||
.isCreatedByUser(true) // 현재는 작성자 기준으로만 조회하므로 true
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -577,19 +556,10 @@ public class MinutesController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 참여 유형별 필터링
|
||||
* 참여 유형별 필터링 - 현재는 사용하지 않음 (작성자 기준으로만 조회)
|
||||
*/
|
||||
private boolean filterByParticipationType(MinutesListResponse.MinutesItem item, String participationType) {
|
||||
if (participationType == null || participationType.isEmpty()) {
|
||||
return true; // 필터 미적용시 모두 표시
|
||||
}
|
||||
|
||||
if ("created".equals(participationType)) {
|
||||
return item.isCreatedByUser(); // 사용자가 생성한 회의록만
|
||||
} else if ("attended".equals(participationType)) {
|
||||
return !item.isCreatedByUser(); // 사용자가 참여만 한 회의록
|
||||
}
|
||||
|
||||
private boolean filterByParticipationType(MinutesListResponse.MinutesItem item, String participationType, String userId) {
|
||||
// 현재는 작성자 기준으로만 조회하므로 항상 true 반환
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -637,7 +607,7 @@ public class MinutesController {
|
||||
private MinutesListResponse.Statistics calculateStatistics(List<MinutesListResponse.MinutesItem> allItems,
|
||||
String participationType, String userId) {
|
||||
List<MinutesListResponse.MinutesItem> filteredItems = allItems.stream()
|
||||
.filter(item -> filterByParticipationType(item, participationType))
|
||||
.filter(item -> filterByParticipationType(item, participationType, userId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
long totalCount = filteredItems.size();
|
||||
|
||||
@ -18,10 +18,8 @@ import org.springframework.stereotype.Component;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -46,7 +44,7 @@ public class DashboardGateway implements DashboardReader {
|
||||
// 1. 다가오는 회의 목록 조회 (향후 30일, 최대 10개)
|
||||
List<Meeting> upcomingMeetings = getUpcomingMeetings(userId);
|
||||
|
||||
// 2. 최근 회의록 목록 조회 (최근 30일, 최대 4개)
|
||||
// 2. 최근 회의록 목록 조회 (최근 7일, 최대 10개)
|
||||
List<Minutes> recentMinutes = getRecentMinutes(userId);
|
||||
|
||||
// 3. 통계 정보 계산 (최근 30일 기준)
|
||||
@ -237,27 +235,36 @@ public class DashboardGateway implements DashboardReader {
|
||||
* 기간별 최근 회의록 목록 조회
|
||||
*/
|
||||
private List<Minutes> getRecentMinutesByPeriod(String userId, LocalDateTime startTime, LocalDateTime endTime) {
|
||||
log.debug("회의록 조회 시작 - userId: {}, startTime: {}, endTime: {}", userId, startTime, endTime);
|
||||
Set<String> userMinutesIds = new HashSet<>();
|
||||
|
||||
// 사용자가 작성한 회의록만 조회 (createdBy = userId)
|
||||
List<MinutesEntity> userMinutes = minutesJpaRepository.findByCreatedBy(userId).stream()
|
||||
.filter(m -> m.getCreatedAt() != null &&
|
||||
m.getCreatedAt().isAfter(startTime) &&
|
||||
m.getCreatedAt().isBefore(endTime))
|
||||
// 작성자로 참여한 회의록 조회
|
||||
List<MinutesEntity> createdMinutes = minutesJpaRepository.findByCreatedBy(userId).stream()
|
||||
.filter(m -> m.getCreatedAt().isAfter(startTime) && m.getCreatedAt().isBefore(endTime))
|
||||
.toList();
|
||||
|
||||
createdMinutes.forEach(m -> userMinutesIds.add(m.getMinutesId()));
|
||||
|
||||
// 참석한 회의의 회의록 조회
|
||||
List<String> participantMeetingIds = meetingParticipantJpaRepository.findByUserId(userId).stream()
|
||||
.map(p -> p.getMeetingId())
|
||||
.toList();
|
||||
|
||||
List<MinutesEntity> participatedMinutes = minutesJpaRepository.findAll().stream()
|
||||
.filter(m -> participantMeetingIds.contains(m.getMeetingId()))
|
||||
.filter(m -> m.getCreatedAt().isAfter(startTime) && m.getCreatedAt().isBefore(endTime))
|
||||
.toList();
|
||||
|
||||
participatedMinutes.forEach(m -> userMinutesIds.add(m.getMinutesId()));
|
||||
|
||||
// 중복 제거 후 최종 수정 시간순 정렬
|
||||
return minutesJpaRepository.findAll().stream()
|
||||
.filter(m -> userMinutesIds.contains(m.getMinutesId()))
|
||||
.sorted((m1, m2) -> {
|
||||
LocalDateTime time1 = m1.getUpdatedAt() != null ? m1.getUpdatedAt() : m1.getCreatedAt();
|
||||
LocalDateTime time2 = m2.getUpdatedAt() != null ? m2.getUpdatedAt() : m2.getCreatedAt();
|
||||
return time2.compareTo(time1); // 최신순
|
||||
})
|
||||
.toList();
|
||||
|
||||
log.debug("조회된 회의록 수: {}", userMinutes.size());
|
||||
userMinutes.forEach(m -> {
|
||||
log.debug(" - minutesId: {}, meetingId: {}, title: {}, createdBy: {}, createdAt: {}",
|
||||
m.getMinutesId(), m.getMeetingId(), m.getTitle(), m.getCreatedBy(), m.getCreatedAt());
|
||||
});
|
||||
|
||||
return userMinutes.stream()
|
||||
// limit 제거 - 상위 메서드에서 필터링
|
||||
.map(MinutesEntity::toDomain)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
@ -76,32 +75,9 @@ public class MinutesGateway implements MinutesReader, MinutesWriter {
|
||||
@Override
|
||||
public Optional<Minutes> findConsolidatedMinutesByMeetingId(String meetingId) {
|
||||
log.debug("회의 ID로 AI 통합 회의록 조회: {}", meetingId);
|
||||
List<MinutesEntity> consolidatedMinutes = minutesJpaRepository.findByMeetingIdAndUserIdIsNull(meetingId);
|
||||
|
||||
if (consolidatedMinutes.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// 여러 개가 있을 경우 가장 최신 것을 반환 (updatedAt 또는 createdAt 기준)
|
||||
return consolidatedMinutes.stream()
|
||||
.sorted((m1, m2) -> {
|
||||
LocalDateTime time1 = m1.getUpdatedAt() != null ? m1.getUpdatedAt() : m1.getCreatedAt();
|
||||
LocalDateTime time2 = m2.getUpdatedAt() != null ? m2.getUpdatedAt() : m2.getCreatedAt();
|
||||
return time2.compareTo(time1); // 최신순
|
||||
})
|
||||
.findFirst()
|
||||
return minutesJpaRepository.findByMeetingIdAndUserIdIsNull(meetingId)
|
||||
.map(MinutesEntity::toDomain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Minutes> findByParticipantUserId(String userId) {
|
||||
log.debug("사용자가 참여한 회의의 회의록 조회: {}", userId);
|
||||
// 사용자가 생성한 회의록과 사용자가 참여한 회의의 회의록을 모두 조회
|
||||
// 현재는 생성자 기준으로만 조회 (추후 참석자 테이블과 조인하여 구현 필요)
|
||||
return minutesJpaRepository.findByCreatedByOrParticipantUserId(userId).stream()
|
||||
.map(MinutesEntity::toDomain)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Minutes save(Minutes minutes) {
|
||||
|
||||
@ -50,20 +50,7 @@ public interface MinutesJpaRepository extends JpaRepository<MinutesEntity, Strin
|
||||
List<MinutesEntity> findByMeetingIdAndUserIdIsNotNull(String meetingId);
|
||||
|
||||
/**
|
||||
* 회의 ID로 AI 통합 회의록 목록 조회 (user_id IS NULL)
|
||||
* 회의 ID로 AI 통합 회의록 조회 (user_id IS NULL)
|
||||
*/
|
||||
List<MinutesEntity> findByMeetingIdAndUserIdIsNull(String meetingId);
|
||||
|
||||
/**
|
||||
* 사용자가 생성했거나 참여한 회의의 회의록 조회
|
||||
* 현재는 생성자 기준으로만 조회 (추후 참석자 테이블과 조인 필요)
|
||||
*
|
||||
* @param userId 사용자 ID
|
||||
* @return 회의록 목록
|
||||
*/
|
||||
default List<MinutesEntity> findByCreatedByOrParticipantUserId(String userId) {
|
||||
// TODO: 참석자 테이블(participants)과 조인하여 참여한 회의의 회의록도 조회하도록 구현 필요
|
||||
// 현재는 임시로 생성자 기준으로만 조회
|
||||
return findByCreatedBy(userId);
|
||||
}
|
||||
Optional<MinutesEntity> findByMeetingIdAndUserIdIsNull(String meetingId);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user