package com.tourguide.modules.feedback.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.tourguide.common.api.PageResponse; import com.tourguide.common.exception.BusinessException; import com.tourguide.modules.feedback.dto.UserFeedbackResponse; import com.tourguide.modules.feedback.entity.UserFeedback; import com.tourguide.modules.feedback.mapper.UserFeedbackMapper; import com.tourguide.modules.user.entity.GuideUser; import com.tourguide.modules.user.entity.MiniUser; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @Service public class UserFeedbackService { private static final Set FEEDBACK_TYPES = new HashSet(Arrays.asList("VISITOR", "GUIDE")); private final UserFeedbackMapper feedbackMapper; public UserFeedbackService(UserFeedbackMapper feedbackMapper) { this.feedbackMapper = feedbackMapper; } public PageResponse page(long page, long size, String feedbackType, String mobile, Integer status, LocalDate startDate, LocalDate endDate) { String normalizedType = normalizeFeedbackType(feedbackType); LambdaQueryWrapper query = new LambdaQueryWrapper() .eq(UserFeedback::getFeedbackType, normalizedType) .like(StringUtils.hasText(mobile), UserFeedback::getUserMobile, mobile == null ? null : mobile.trim()) .eq(status != null, UserFeedback::getStatus, status) .ge(startDate != null, UserFeedback::getFeedbackAt, startDate == null ? null : startDate.atStartOfDay()) .lt(endDate != null, UserFeedback::getFeedbackAt, endDate == null ? null : endDate.plusDays(1).atStartOfDay()) .orderByAsc(UserFeedback::getStatus) .orderByDesc(UserFeedback::getFeedbackAt) .orderByDesc(UserFeedback::getId); Page result = feedbackMapper.selectPage(new Page(page, size), query); return new PageResponse( result.getRecords().stream().map(UserFeedbackResponse::new).collect(Collectors.toList()), result.getTotal(), result.getCurrent(), result.getSize()); } public UserFeedbackResponse detail(Long id) { return new UserFeedbackResponse(requireFeedback(id)); } @Transactional public UserFeedbackResponse createVisitor(MiniUser user, String content) { return create("VISITOR", user.getId(), resolveUserName(user), user.getMobile(), content); } @Transactional public UserFeedbackResponse createGuide(GuideUser guide, String content) { return create("GUIDE", guide.getId(), resolveUserName(guide), guide.getMobile(), content); } private UserFeedbackResponse create(String feedbackType, Long userId, String userName, String userMobile, String content) { UserFeedback feedback = new UserFeedback(); feedback.setFeedbackNo(generateFeedbackNo()); feedback.setFeedbackType(feedbackType); feedback.setUserId(userId); feedback.setUserName(userName); feedback.setUserMobile(userMobile); feedback.setContent(content.trim()); feedback.setFeedbackAt(LocalDateTime.now()); feedback.setStatus(0); feedbackMapper.insert(feedback); return new UserFeedbackResponse(feedback); } @Transactional public UserFeedbackResponse process(Long id, String result, Long processorId, String processorName) { UserFeedback feedback = requireFeedback(id); if (Integer.valueOf(1).equals(feedback.getStatus())) { throw new BusinessException(409, "该反馈已处理,请勿重复操作"); } feedback.setStatus(1); feedback.setProcessResult(result.trim()); feedback.setProcessedBy(processorId); feedback.setProcessedByName(processorName); feedback.setProcessedAt(LocalDateTime.now()); feedbackMapper.updateById(feedback); return new UserFeedbackResponse(feedback); } private UserFeedback requireFeedback(Long id) { UserFeedback feedback = feedbackMapper.selectById(id); if (feedback == null) throw new BusinessException(404, "反馈不存在"); return feedback; } private String normalizeFeedbackType(String feedbackType) { String normalizedType = StringUtils.hasText(feedbackType) ? feedbackType.trim().toUpperCase() : "VISITOR"; if (!FEEDBACK_TYPES.contains(normalizedType)) throw new BusinessException(400, "反馈类型不正确"); return normalizedType; } private String resolveUserName(MiniUser user) { if (StringUtils.hasText(user.getRealName())) return user.getRealName(); if (StringUtils.hasText(user.getNickname())) return user.getNickname(); return user.getUsername(); } private String resolveUserName(GuideUser guide) { if (StringUtils.hasText(guide.getRealName())) return guide.getRealName(); return guide.getUsername(); } private String generateFeedbackNo() { String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")); String random = UUID.randomUUID().toString().replace("-", "").substring(0, 5).toUpperCase(); return "FB" + time + random; } }