**实现要点分析**: 1. **动态地图加载**: 算法从数据库动态加载地图数据,包括障碍物信息和地图尺寸,使得路径规划能够适应地图的变化。 2. **优先队列优化**: 使用优先队列(PriorityQueue)存储开放列表,确保每次都能高效地选择F值最小的节点,大大提高了算法效率。 3. **曼哈顿距离启发函数**: 选择曼哈顿距离作为启发函数,适合网格化的移动模式,能够准确估计网格间的距离。 4. **路径重建**: 通过记录每个节点的父节点,实现了从终点回溯到起点的路径重建,返回完整的路径点列表。 **程序流程图**: ```mermaid flowchart TD A[开始] --> B[加载地图数据] B --> C[初始化开放列表和关闭列表] C --> D[将起点加入开放列表] D --> E{开放列表为空?} E -->|是| F[返回空路径] E -->|否| G[从开放列表取出F值最小的节点] G --> H{是终点?} H -->|是| I[重建并返回路径] H -->|否| J[处理相邻节点] J --> E ``` **API接口**: ```java @RestController @RequestMapping("/api/pathfinding") @RequiredArgsConstructor public class PathfindingController { private final AStarService aStarService; @GetMapping("/find") @PreAuthorize("hasRole('GRID_WORKER')") public ResponseEntity> findPath( @RequestParam int startX, @RequestParam int startY, @RequestParam int endX, @RequestParam int endY) { Point start = new Point(startX, startY); Point end = new Point(endX, endY); List path = aStarService.findPath(start, end); return ResponseEntity.ok(path); } } ``` ### 3. 反馈管理模块 反馈管理模块是系统的核心业务模块之一,负责处理用户提交的环境问题反馈。我实现了完整的反馈提交、审核和处理流程,包括多条件查询、状态流转和文件上传等功能。 **关键代码展示**: ```java @RestController @RequestMapping("/api/feedback") @RequiredArgsConstructor public class FeedbackController { private final FeedbackService feedbackService; /** * 提交反馈(正式接口) * 使用multipart/form-data格式提交反馈,支持附件上传 */ @PostMapping(value = "/submit", consumes = {"multipart/form-data"}) @PreAuthorize("isAuthenticated()") public ResponseEntity submitFeedback( @Valid @RequestPart("feedback") FeedbackSubmissionRequest request, @RequestPart(value = "files", required = false) MultipartFile[] files, @AuthenticationPrincipal CustomUserDetails userDetails) { Feedback createdFeedback = feedbackService.submitFeedback(request, files); return new ResponseEntity<>(createdFeedback, HttpStatus.CREATED); } /** * 获取所有反馈(分页+多条件过滤) * 支持按状态、污染类型、严重程度、地理位置、时间范围和关键词进行组合查询 */ @GetMapping @PreAuthorize("isAuthenticated()") public ResponseEntity> getAllFeedback( @AuthenticationPrincipal CustomUserDetails userDetails, @RequestParam(required = false) FeedbackStatus status, @RequestParam(required = false) PollutionType pollutionType, @RequestParam(required = false) SeverityLevel severityLevel, @RequestParam(required = false) String cityName, @RequestParam(required = false) String districtName, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate, @RequestParam(required = false) String keyword, Pageable pageable) { Page feedbackPage = feedbackService.getFeedback( userDetails, status, pollutionType, severityLevel, cityName, districtName, startDate, endDate, keyword, pageable); return ResponseEntity.ok(feedbackPage); } /** * 处理反馈 (例如, 批准) */ @PostMapping("/{id}/process") @PreAuthorize("hasAnyRole('ADMIN', 'SUPERVISOR')") public ResponseEntity processFeedback( @PathVariable Long id, @Valid @RequestBody ProcessFeedbackRequest request) { FeedbackResponseDTO updatedFeedback = feedbackService.processFeedback(id, request); return ResponseEntity.ok(updatedFeedback); } } ``` **服务层实现**: ```java @Service @RequiredArgsConstructor public class FeedbackServiceImpl implements FeedbackService { private final FeedbackRepository feedbackRepository; private final UserAccountRepository userAccountRepository; private final FileStorageService fileStorageService; private final ApplicationEventPublisher eventPublisher; @Override public Feedback submitFeedback(FeedbackSubmissionRequest request, MultipartFile[] files) { // 1. 获取当前用户 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String email = authentication.getName(); UserAccount user = userAccountRepository.findByEmail(email) .orElseThrow(() -> new ResourceNotFoundException("User", "email", email)); // 2. 创建反馈实体 Feedback feedback = new Feedback(); feedback.setTitle(request.getTitle()); feedback.setDescription(request.getDescription()); feedback.setPollutionType(request.getPollutionType()); feedback.setSeverityLevel(request.getSeverityLevel()); feedback.setLatitude(request.getLatitude()); feedback.setLongitude(request.getLongitude()); feedback.setTextAddress(request.getTextAddress()); feedback.setGridX(request.getGridX()); feedback.setGridY(request.getGridY()); feedback.setStatus(FeedbackStatus.SUBMITTED); feedback.setSubmitter(user); feedback.setEventId(generateEventId()); // 3. 保存反馈 Feedback savedFeedback = feedbackRepository.save(feedback); // 4. 处理附件 if (files != null && files.length > 0) { List attachments = new ArrayList<>(); for (MultipartFile file : files) { String fileName = fileStorageService.storeFile(file); Attachment attachment = new Attachment(); attachment.setFileName(fileName); attachment.setFilePath("/uploads/" + fileName); attachment.setFileType(file.getContentType()); attachment.setFileSize(file.getSize()); attachments.add(attachment); } savedFeedback.setAttachments(attachments); feedbackRepository.save(savedFeedback); } // 5. 发布事件,触发AI审核 eventPublisher.publishEvent(new FeedbackSubmittedEvent(savedFeedback)); return savedFeedback; } @Override public FeedbackResponseDTO processFeedback(Long id, ProcessFeedbackRequest request) { Feedback feedback = feedbackRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Feedback", "id", id)); // 验证状态转换是否有效 if (!isValidStatusTransition(feedback.getStatus(), request.getStatus())) { throw new IllegalStateException("Invalid status transition from " + feedback.getStatus() + " to " + request.getStatus()); } // 更新反馈状态 feedback.setStatus(request.getStatus()); // 如果批准反馈,则更新为PENDING_ASSIGNMENT状态 if (request.getStatus() == FeedbackStatus.APPROVED) { feedback.setStatus(FeedbackStatus.PENDING_ASSIGNMENT); } Feedback updatedFeedback = feedbackRepository.save(feedback); // 如果反馈被批准,发布事件通知任务管理模块 if (request.getStatus() == FeedbackStatus.APPROVED) { eventPublisher.publishEvent(new FeedbackApprovedEvent(updatedFeedback)); } return mapToDTO(updatedFeedback); } // 生成唯一的事件ID private String generateEventId() { return "EMS-" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase(); } // 验证状态转换是否有效 private boolean isValidStatusTransition(FeedbackStatus current, FeedbackStatus next) { // 实现状态机逻辑 switch (current) { case SUBMITTED: return next == FeedbackStatus.AI_REVIEWED; case AI_REVIEWED: return next == FeedbackStatus.PENDING_REVIEW; case PENDING_REVIEW: return next == FeedbackStatus.APPROVED || next == FeedbackStatus.REJECTED; case APPROVED: return next == FeedbackStatus.PENDING_ASSIGNMENT; case PENDING_ASSIGNMENT: return next == FeedbackStatus.ASSIGNED; case ASSIGNED: return next == FeedbackStatus.PROCESSED; case PROCESSED: return next == FeedbackStatus.CLOSED; default: return false; } } } ``` **实现要点分析**: 1. **多部分表单处理**: 使用`@RequestPart`注解同时处理JSON数据和文件上传,实现了富媒体反馈提交。 2. **事件驱动架构**: 通过Spring的事件机制,实现了反馈提交后的异步处理,如AI审核和任务创建,提高了系统响应速度。 3. **状态机模式**: 使用状态机模式管理反馈的生命周期,确保状态转换的合法性,防止非法操作。 4. **多条件动态查询**: 实现了灵活的多条件组合查询,支持按状态、类型、严重程度、地理位置和时间范围等进行过滤。