每日总结


package com.mentalhealth.service;
import com.mentalhealth.entity.Consultant;
import com.mentalhealth.entity.ConsultationSession;
import com.mentalhealth.repository.ConsultationSessionRepository;
import com.mentalhealth.repository.ConsultantRepository;
import com.mentalhealth.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
public class StatisticsService {
private final UserRepository userRepository;
private final ConsultantRepository consultantRepository;
private final ConsultationSessionRepository sessionRepository;
public Map<String, Object> getSystemStatistics() {
Map<String, Object> stats = new HashMap<>();
long totalUsers = userRepository.count();
long totalConsultants = consultantRepository.count();
long totalSessions = sessionRepository.count();
// 今日会话统计
LocalDateTime startOfToday = LocalDate.now().atStartOfDay();
long todaySessions = sessionRepository.countByScheduledTimeAfter(startOfToday);
// 本月会话统计
LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
long monthlySessions = sessionRepository.countByScheduledTimeAfter(startOfMonth);
// 各种状态统计
long pendingSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.PENDING);
long confirmedSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.CONFIRMED);
long inProgressSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.IN_PROGRESS);
long completedSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.COMPLETED);
long cancelledSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.CANCELLED);
// 计算总收入
Double totalRevenue = calculateTotalRevenue();
stats.put("totalUsers", totalUsers);
stats.put("totalConsultants", totalConsultants);
stats.put("totalSessions", totalSessions);
stats.put("todaySessions", todaySessions);
stats.put("monthlySessions", monthlySessions);
stats.put("pendingSessions", pendingSessions);
stats.put("confirmedSessions", confirmedSessions);
stats.put("inProgressSessions", inProgressSessions);
stats.put("completedSessions", completedSessions);
stats.put("cancelledSessions", cancelledSessions);
stats.put("totalRevenue", totalRevenue != null ? totalRevenue : 0);
stats.put("completionRate", calculateCompletionRate());
stats.put("cancellationRate", calculateCancellationRate());
// 获取状态分布
List<Object[]> statusDistribution = sessionRepository.countSessionsByStatusForSystem();
Map<String, Long> statusStats = new HashMap<>();
for (Object[] result : statusDistribution) {
String status = result[0].toString();
Long count = (Long) result[1];
statusStats.put(status, count);
}
stats.put("statusDistribution", statusStats);
return stats;
}
public Map<String, Object> getConsultantStatistics(Long consultantId) {
Map<String, Object> stats = new HashMap<>();
Consultant consultant = consultantRepository.findById(consultantId)
.orElseThrow(() -> new RuntimeException("咨询师不存在"));
long totalSessions = sessionRepository.countByConsultantId(consultantId);
long completedSessions = sessionRepository.countByConsultantIdAndStatus(
consultantId, ConsultationSession.SessionStatus.COMPLETED);
long pendingSessions = sessionRepository.countByConsultantIdAndStatus(
consultantId, ConsultationSession.SessionStatus.PENDING);
long inProgressSessions = sessionRepository.countByConsultantIdAndStatus(
consultantId, ConsultationSession.SessionStatus.IN_PROGRESS);
double averageRating = consultant.getRating() != null ? consultant.getRating() : 0.0;
// 在 Service 层计算平均响应时间
Double averageResponseTime = calculateAverageResponseTime(consultantId);
// 修正:使用正确的方法名 - 基于 consultantId 的方法
Double satisfactionRate = sessionRepository.findAverageRatingByConsultantId(consultantId);
Double totalRevenue = sessionRepository.findTotalRevenueByConsultant(consultantId);
// 今日统计
LocalDateTime startOfToday = LocalDate.now().atStartOfDay();
long todaySessions = sessionRepository.countByConsultantIdAndScheduledTimeAfter(consultantId, startOfToday);
// 本月统计
LocalDateTime startOfMonth = LocalDate.now().withDayOfMonth(1).atStartOfDay();
long monthlySessions = sessionRepository.countByConsultantIdAndScheduledTimeAfter(consultantId, startOfMonth);
stats.put("consultantName", consultant.getUser().getUsername());
stats.put("realName", consultant.getRealName());
stats.put("experienceYears", consultant.getExperienceYears());
stats.put("totalSessions", totalSessions);
stats.put("completedSessions", completedSessions);
stats.put("pendingSessions", pendingSessions);
stats.put("inProgressSessions", inProgressSessions);
stats.put("todaySessions", todaySessions);
stats.put("monthlySessions", monthlySessions);
stats.put("averageRating", averageRating);
stats.put("averageResponseTime", averageResponseTime != null ? Math.round(averageResponseTime) : 0);
stats.put("satisfactionRate", satisfactionRate != null ? satisfactionRate : 0.0);
stats.put("totalRevenue", totalRevenue != null ? totalRevenue : 0.0);
stats.put("completionRate", totalSessions > 0 ?
(double) completedSessions / totalSessions * 100 : 0);
stats.put("responseRate", totalSessions > 0 ?
(double) (completedSessions + inProgressSessions) / totalSessions * 100 : 0);
// 获取状态分布
List<Object[]> statusDistribution = sessionRepository.countSessionsByStatusForConsultant(consultantId);
Map<String, Long> statusStats = new HashMap<>();
for (Object[] result : statusDistribution) {
String status = result[0].toString();
Long count = (Long) result[1];
statusStats.put(status, count);
}
stats.put("statusDistribution", statusStats);
// 获取热门咨询类型
List<Object[]> popularTypes = sessionRepository.findPopularConsultationTypesByConsultant(consultantId);
Map<String, Long> typeStats = new HashMap<>();
for (Object[] result : popularTypes) {
String type = result[0].toString();
Long count = (Long) result[1];
typeStats.put(type, count);
}
stats.put("consultationTypes", typeStats);
return stats;
}
public Map<String, Object> getUserStatistics(Long userId) {
Map<String, Object> stats = new HashMap<>();
// 修正:添加缺失的方法或使用现有方法
long totalSessions = sessionRepository.countByUserIdAndStatus(userId, ConsultationSession.SessionStatus.COMPLETED);
long pendingSessions = sessionRepository.countByUserIdAndStatus(userId, ConsultationSession.SessionStatus.PENDING);
long completedSessions = sessionRepository.countByUserIdAndStatus(userId, ConsultationSession.SessionStatus.COMPLETED);
// 平均评分(用户给咨询师的评分)
Double averageGivenRating = sessionRepository.findAverageRatingByUser(userId);
stats.put("totalSessions", totalSessions);
stats.put("pendingSessions", pendingSessions);
stats.put("completedSessions", completedSessions);
stats.put("averageGivenRating", averageGivenRating != null ? averageGivenRating : 0.0);
stats.put("consultationFrequency", calculateConsultationFrequency(userId));
return stats;
}
public Map<String, Object> getMonthlyStatistics(int year, int month) {
Map<String, Object> stats = new HashMap<>();
LocalDateTime startOfMonth = LocalDate.of(year, month, 1).atStartOfDay();
LocalDateTime endOfMonth = startOfMonth.plusMonths(1).minusSeconds(1);
long monthlySessions = sessionRepository.countByScheduledTimeBetween(startOfMonth, endOfMonth);
// 修正:传递两个参数(开始时间和结束时间)
long monthlyCompleted = sessionRepository.countMonthlyCompletedSessions(startOfMonth, endOfMonth);
double monthlyRevenue = calculateMonthlyRevenue(year, month);
stats.put("year", year);
stats.put("month", month);
stats.put("totalSessions", monthlySessions);
stats.put("completedSessions", monthlyCompleted);
stats.put("revenue", monthlyRevenue);
stats.put("completionRate", monthlySessions > 0 ? (double) monthlyCompleted / monthlySessions * 100 : 0);
return stats;
}
// 在 Service 层计算平均响应时间
private Double calculateAverageResponseTime(Long consultantId) {
List<ConsultationSession> sessions = sessionRepository.findByConsultantId(consultantId);
long totalMinutes = 0;
int count = 0;
for (ConsultationSession session : sessions) {
if (session.getActualStartTime() != null && session.getScheduledTime() != null) {
java.time.Duration duration = java.time.Duration.between(session.getScheduledTime(), session.getActualStartTime());
totalMinutes += duration.toMinutes();
count++;
}
}
return count > 0 ? (double) totalMinutes / count : null;
}
private Double calculateTotalRevenue() {
// 计算所有咨询师的总收入
List<Consultant> consultants = consultantRepository.findAll();
double totalRevenue = 0.0;
for (Consultant consultant : consultants) {
Double revenue = sessionRepository.findTotalRevenueByConsultant(consultant.getId());
if (revenue != null) {
totalRevenue += revenue;
}
}
return totalRevenue;
}
private double calculateCompletionRate() {
long totalSessions = sessionRepository.count();
long completedSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.COMPLETED);
return totalSessions > 0 ? (double) completedSessions / totalSessions * 100 : 0;
}
private double calculateCancellationRate() {
long totalSessions = sessionRepository.count();
long cancelledSessions = sessionRepository.countByStatus(ConsultationSession.SessionStatus.CANCELLED);
return totalSessions > 0 ? (double) cancelledSessions / totalSessions * 100 : 0;
}
private double calculateConsultationFrequency(Long userId) {
long completedSessions = sessionRepository.countByUserIdAndStatus(userId, ConsultationSession.SessionStatus.COMPLETED);
// 假设用户注册时间为3个月前(简化处理)
long monthsSinceRegistration = 3;
return monthsSinceRegistration > 0 ? (double) completedSessions / monthsSinceRegistration : 0;
}
private double calculateMonthlyRevenue(int year, int month) {
LocalDateTime startOfMonth = LocalDate.of(year, month, 1).atStartOfDay();
LocalDateTime endOfMonth = startOfMonth.plusMonths(1).minusSeconds(1);
// 计算所有咨询师的月度总收入
List<Consultant> consultants = consultantRepository.findAll();
double monthlyRevenue = 0.0;
for (Consultant consultant : consultants) {
Double revenue = sessionRepository.findMonthlyRevenueByConsultant(
consultant.getId(), startOfMonth, endOfMonth);
if (revenue != null) {
monthlyRevenue += revenue;
}
}
return monthlyRevenue;
}
}
package com.mentalhealth.service;
import com.mentalhealth.dto.;
import com.mentalhealth.entity.;
import com.mentalhealth.repository.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class ConsultationService {
private final ConsultationRequestRepository requestRepository;
private final ConsultantRepository consultantRepository;
private final ConsultationSessionRepository sessionRepository;
private final MessageService messageService;
private final UserRepository userRepository;
@Transactional
public ConsultationRequest createConsultationRequest(ConsultationRequestDTO requestDTO) {
User user = userRepository.findById(requestDTO.getUserId())
.orElseThrow(() -> new RuntimeException("用户不存在"));
ConsultationRequest request = new ConsultationRequest();
request.setUser(user);
// 修正字段映射:problemDescription -> description
request.setDescription(requestDTO.getProblemDescription());
// 修正字段映射:durationMonths -> duration
request.setDuration(requestDTO.getDurationMonths());
// 修正字段映射:preferredType -> consultationType
request.setConsultationType(requestDTO.getPreferredType());
request.setStatus(ConsultationRequest.RequestStatus.PENDING);
request.setCreateTime(LocalDateTime.now());
ConsultationRequest savedRequest = requestRepository.save(request);
// 智能匹配咨询师
matchConsultants(savedRequest);
return savedRequest;
}
private void matchConsultants(ConsultationRequest request) {
// 基于问题描述和偏好进行智能匹配
List<Consultant> matchedConsultants = getAvailableConsultants(
extractExpertiseArea(request.getDescription()), // 使用 getDescription() 而不是 getProblemDescription()
request.getConsultationType() != null ? request.getConsultationType().name() : null // 使用
// getConsultationType()
);
// 发送匹配通知给咨询师
for (Consultant consultant : matchedConsultants) {
String messageContent = String.format(
"系统为您匹配到咨询师:%s,擅长领域:%s",
consultant.getUser().getUsername(),
consultant.getExpertiseAreas() != null ? String.join(",", consultant.getExpertiseAreas()) : "未设置");
messageService.sendSystemMessage(
consultant.getUser().getId(),
request.getUser().getId(),
messageContent);
}
// 发送匹配结果通知给用户
String userMessageContent;
if (matchedConsultants.isEmpty()) {
userMessageContent = "您的咨询请求已提交,系统正在为您寻找合适的咨询师,请耐心等待。";
} else {
userMessageContent = String.format(
"系统已为您匹配到%d位合适的咨询师,我们将尽快安排您的咨询。",
matchedConsultants.size());
}
messageService.sendSystemMessage(
0L, // 系统消息
request.getUser().getId(),
userMessageContent);
}
private String extractExpertiseArea(String problemDescription) {
// 简单的关键词匹配,实际应该使用NLP技术
if (problemDescription == null)
return "一般心理问题";
if (problemDescription.contains("焦虑"))
return "焦虑";
if (problemDescription.contains("抑郁"))
return "抑郁";
if (problemDescription.contains("婚姻"))
return "婚姻家庭";
if (problemDescription.contains("亲子"))
return "亲子关系";
return "一般心理问题";
}
/**
* 根据ID获取咨询师详情
*/
public Consultant getConsultantById(Long id) {
return consultantRepository.findById(id)
.orElseThrow(() -> new RuntimeException("咨询师不存在,ID: " + id));
}
/**
* 获取所有可用咨询师
*/
public List<Consultant> getAllAvailableConsultants() {
return getAvailableConsultants(null, null);
}
/**
* 根据专业领域筛选咨询师
*/
public List<Consultant> getConsultantsByExpertise(String expertiseArea) {
return getAvailableConsultants(expertiseArea, null);
}
/**
* 获取可用咨询师
*/
public List<Consultant> getAvailableConsultants(String expertiseArea, String preferredType) {
Specification<Consultant> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
// 只查询已批准的咨询师
predicates.add(cb.equal(root.get("status"), "APPROVED"));
predicates.add(cb.isTrue(root.get("available")));
if (expertiseArea != null && !expertiseArea.isEmpty()) {
predicates.add(cb.isMember(expertiseArea, root.get("expertiseAreas")));
}
// 考虑咨询方式偏好
if (preferredType != null && !preferredType.isEmpty()) {
predicates.add(cb.isMember(preferredType, root.get("therapyMethods")));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
return consultantRepository.findAll(spec);
}
public List<Consultant> searchConsultants(ConsultantSearchDTO searchDTO) {
Specification<Consultant> spec = Specification.where(null);
if (searchDTO.getExpertiseArea() != null) {
spec = spec.and((root, query, cb) -> cb.isMember(searchDTO.getExpertiseArea(), root.get("expertiseAreas")));
}
if (searchDTO.getTherapyMethod() != null) {
spec = spec.and((root, query, cb) -> cb.isMember(searchDTO.getTherapyMethod(), root.get("therapyMethods")));
}
if (searchDTO.getKeyword() != null) {
spec = spec.and(
(root, query, cb) -> cb.like(root.get("user").get("username"), "%" + searchDTO.getKeyword() + "%"));
}
if (searchDTO.getGender() != null) {
spec = spec.and((root, query, cb) -> cb.equal(root.get("user").get("gender"), searchDTO.getGender()));
}
if (searchDTO.getMinExperience() != null) {
spec = spec.and((root, query, cb) -> cb.greaterThanOrEqualTo(root.get("experienceYears"),
searchDTO.getMinExperience()));
}
if (searchDTO.getMinRating() != null) {
spec = spec.and((root, query, cb) -> cb.greaterThanOrEqualTo(root.get("rating"), searchDTO.getMinRating()));
}
// 只返回已批准且可用的咨询师
spec = spec.and((root, query, cb) -> cb.equal(root.get("status"), "APPROVED"));
spec = spec.and((root, query, cb) -> cb.isTrue(root.get("available")));
return consultantRepository.findAll(spec);
}
@Transactional
public ConsultationSession bookConsultation(BookingDTO bookingDTO) {
// 验证用户存在
User user = userRepository.findById(bookingDTO.getUserId())
.orElseThrow(() -> new RuntimeException("用户不存在"));
Consultant consultant = consultantRepository.findById(bookingDTO.getConsultantId())
.orElseThrow(() -> new RuntimeException("咨询师不存在"));
// 检查咨询师是否已批准且可用
if (!"APPROVED".equals(consultant.getStatus()) || !Boolean.TRUE.equals(consultant.getAvailable())) {
throw new RuntimeException("该咨询师暂不可用");
}
ConsultationSession session = new ConsultationSession();
session.setUserId(bookingDTO.getUserId()); // 使用 setUserId 而不是 setUser
session.setConsultant(consultant); // 设置关联的consultant对象
session.setConsultantId(consultant.getId()); // 同时显式设置consultantId字段
session.setType(bookingDTO.getType());
session.setDuration(bookingDTO.getDuration());
session.setScheduledTime(bookingDTO.getScheduledTime());
session.setPrice(calculatePrice(consultant, bookingDTO.getDuration(), bookingDTO.getType()));
session.setStatus(ConsultationSession.SessionStatus.PENDING);
session.setCreateTime(LocalDateTime.now());
ConsultationSession savedSession = sessionRepository.save(session);
// 发送通知给用户
String userMessage = String.format("您已成功预约咨询师%s,时间:%s,咨询类型:%s,时长:%d分钟",
consultant.getUser().getUsername(),
savedSession.getScheduledTime()
.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
savedSession.getType().getDescription(),
savedSession.getDuration());
messageService.sendSystemMessage(0L, user.getId(), userMessage);
// 发送通知给咨询师
String consultantMessage = String.format("用户%s已预约您的咨询,时间:%s,咨询类型:%s,时长:%d分钟",
user.getUsername(),
savedSession.getScheduledTime()
.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")),
savedSession.getType().getDescription(),
savedSession.getDuration());
messageService.sendSystemMessage(0L, consultant.getUser().getId(), consultantMessage);
return savedSession;
}
private BigDecimal calculatePrice(Consultant consultant, Integer duration,
com.mentalhealth.entity.ConsultationType consultationType) {
// 将 Double 转换为 BigDecimal
BigDecimal hourlyRate = consultant.getPricePerHour() != null ? BigDecimal.valueOf(consultant.getPricePerHour())
: BigDecimal.valueOf(100);
// 不同咨询方式的价格系数,与前端保持一致
BigDecimal multiplier = BigDecimal.valueOf(1.0);
if (com.mentalhealth.entity.ConsultationType.TEXT.equals(consultationType)) {
multiplier = BigDecimal.valueOf(0.8);
} else if (com.mentalhealth.entity.ConsultationType.VIDEO.equals(consultationType)) {
multiplier = BigDecimal.valueOf(1.2);
}
return hourlyRate.multiply(
BigDecimal.valueOf(duration).divide(BigDecimal.valueOf(60), 2, BigDecimal.ROUND_HALF_UP))
.multiply(multiplier);
}
public List<ConsultationSession> getUserConsultationHistory(Long userId, List<String> statusList, String type) {
List<ConsultationSession> allSessions = sessionRepository.findByUserIdOrderByScheduledTimeDesc(userId);
// 根据状态过滤
if (statusList != null && !statusList.isEmpty()) {
List<ConsultationSession.SessionStatus> statuses = statusList.stream()
.filter(status -> status != null && !status.isEmpty() && !"all".equals(status))
.map(status -> {
try {
return ConsultationSession.SessionStatus.valueOf(status.toUpperCase());
} catch (IllegalArgumentException e) {
// 忽略无效的状态值
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (!statuses.isEmpty()) {
allSessions = allSessions.stream()
.filter(session -> statuses.contains(session.getStatus()))
.collect(Collectors.toList());
}
}
// 根据类型过滤
if (type != null && !type.isEmpty() && !"all".equals(type)) {
try {
ConsultationType consultationType = ConsultationType.valueOf(type.toUpperCase());
allSessions = allSessions.stream()
.filter(session -> session.getType() == consultationType)
.collect(Collectors.toList());
} catch (IllegalArgumentException e) {
// 忽略无效的类型值
}
}
return allSessions;
}
/**
* 获取咨询师的咨询记录
*/
public List<ConsultationSession> getConsultantSessions(Long consultantId) {
return sessionRepository.findByConsultantIdOrderByScheduledTimeDesc(consultantId);
}
@Transactional
public ConsultationSession rateConsultation(Long sessionId, RatingDTO ratingDTO) {
ConsultationSession session = sessionRepository.findById(sessionId)
.orElseThrow(() -> new RuntimeException("咨询记录不存在"));
// 检查会话是否已完成
if (session.getStatus() != ConsultationSession.SessionStatus.COMPLETED) {
throw new RuntimeException("只能对已完成的咨询进行评价");
}
session.setRating(ratingDTO.getRating());
session.setUserReview(ratingDTO.getReview());
// 更新咨询师评分
updateConsultantRating(session.getConsultantId());
return sessionRepository.save(session);
}
/**
* 更新咨询师评分
*/
private void updateConsultantRating(Long consultantId) {
List<ConsultationSession> sessions = sessionRepository.findByConsultantIdOrderByScheduledTimeDesc(consultantId)
.stream()
.filter(session -> session.getRating() != null)
.collect(Collectors.toList());
if (!sessions.isEmpty()) {
double averageRating = sessions.stream()
.mapToInt(ConsultationSession::getRating)
.average()
.orElse(0.0);
Consultant consultant = consultantRepository.findById(consultantId)
.orElseThrow(() -> new RuntimeException("咨询师不存在"));
consultant.setRating(averageRating);
consultantRepository.save(consultant);
}
}
/**
* 取消咨询预约
*/
@Transactional
public ConsultationSession cancelConsultation(Long sessionId, String reason) {
ConsultationSession session = sessionRepository.findById(sessionId)
.orElseThrow(() -> new RuntimeException("咨询记录不存在"));
if (session.getStatus() != ConsultationSession.SessionStatus.PENDING &&
session.getStatus() != ConsultationSession.SessionStatus.CONFIRMED) {
throw new RuntimeException("只能取消待确认或已确认的咨询");
}
session.setStatus(ConsultationSession.SessionStatus.CANCELLED);
// 获取用户和咨询师信息来发送通知
User user = userRepository.findById(session.getUserId())
.orElseThrow(() -> new RuntimeException("用户不存在"));
Consultant consultant = consultantRepository.findById(session.getConsultantId())
.orElseThrow(() -> new RuntimeException("咨询师不存在"));
// 发送取消通知
messageService.sendSystemMessage(
user.getId(),
consultant.getUser().getId(),
"咨询预约已取消,原因:" + reason);
return sessionRepository.save(session);
}
/**
* 开始咨询会话
*/
@Transactional
public ConsultationSession startConsultation(Long sessionId) {
ConsultationSession session = sessionRepository.findById(sessionId)
.orElseThrow(() -> new RuntimeException("咨询记录不存在"));
session.setStatus(ConsultationSession.SessionStatus.IN_PROGRESS);
session.setActualStartTime(LocalDateTime.now());
return sessionRepository.save(session);
}
/**
* 结束咨询会话
*/
@Transactional
public ConsultationSession completeConsultation(Long sessionId, String summary, String feedback) {
ConsultationSession session = sessionRepository.findById(sessionId)
.orElseThrow(() -> new RuntimeException("咨询记录不存在"));
session.setStatus(ConsultationSession.SessionStatus.COMPLETED);
session.setEndTime(LocalDateTime.now());
session.setSummary(summary);
session.setConsultantFeedback(feedback);
return sessionRepository.save(session);
}
/**
* 获取用户的所有咨询请求
*/
public List<ConsultationRequest> getUserConsultationRequests(Long userId) {
return requestRepository.findByUserId(userId);
}
/**
* 根据状态获取咨询请求
*/
public List<ConsultationRequest> getConsultationRequestsByStatus(ConsultationRequest.RequestStatus status) {
return requestRepository.findByStatus(status);
}
/**
* 获取咨询会话详情
*/
public ConsultationSession getConsultationSession(Long sessionId) {
return sessionRepository.findById(sessionId)
.orElseThrow(() -> new RuntimeException("咨询记录不存在"));
}
/**
* 获取咨询会话详情(包含用户和咨询师信息)
*/
public ConsultationSessionDetailDTO getSessionDetail(Long sessionId) {
ConsultationSession session = sessionRepository.findById(sessionId)
.orElseThrow(() -> new RuntimeException("咨询记录不存在"));
User user = userRepository.findById(session.getUserId())
.orElseThrow(() -> new RuntimeException("用户不存在"));
Consultant consultant = consultantRepository.findById(session.getConsultantId())
.orElseThrow(() -> new RuntimeException("咨询师不存在"));
ConsultationSessionDetailDTO detailDTO = new ConsultationSessionDetailDTO();
detailDTO.setSession(session);
detailDTO.setUser(user);
detailDTO.setConsultant(consultant);
return detailDTO;
}
/**
* 获取咨询师未来指定天数的日程安排
*/
public List<ConsultationSession> getConsultantSchedule(Long consultantId, int days) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime endTime = now.plusDays(days);
return sessionRepository.findByConsultantIdAndScheduledTimeBetweenOrderByScheduledTimeAsc(
consultantId, now, endTime);
}
/**
* 获取用户即将开始的预约(当前时间前后10分钟内)
*/
public Optional<ConsultationSession> getUserUpcomingSession(Long userId) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime before = now.minusMinutes(10);
LocalDateTime after = now.plusMinutes(10);
return sessionRepository.findByUserIdAndScheduledTimeBetweenAndStatusInOrderByScheduledTimeAsc(
userId, before, after,
Arrays.asList(ConsultationSession.SessionStatus.PENDING,
ConsultationSession.SessionStatus.CONFIRMED))
.stream().findFirst();
}
}

浙公网安备 33010602011771号