You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

78 lines
4.2 KiB

package com.mydreamjob.review;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@Repository
public interface JobReviewRepository extends JpaRepository<JobReview, Long> {
Optional<JobReview> findByJobIdAndStudentUserId(Long jobId, Long studentUserId);
Page<JobReview> findByJobIdAndStatusOrderByCreatedAtDesc(Long jobId, String status, Pageable pageable);
/** 公开列表:仅 PUBLISHED 且审核状态为 AUTO_APPROVED/APPROVED */
Page<JobReview> findByJobIdAndStatusAndModerationStatusInOrderByCreatedAtDesc(
Long jobId, String status, Collection<String> moderationStatuses, Pageable pageable);
boolean existsByJobIdAndStudentUserId(Long jobId, Long studentUserId);
List<JobReview> findByJobIdAndStatus(Long jobId, String status);
/** 公开汇总:仅 PUBLISHED 且审核通过(AUTO_APPROVED/APPROVED) */
List<JobReview> findByJobIdAndStatusAndModerationStatusIn(
Long jobId, String status, Collection<String> moderationStatuses);
// ── 防刷规则查询 ──────────────────────────────────────────
long countByStudentUserIdAndCreatedAtAfter(Long studentUserId, LocalDateTime after);
boolean existsByJobIdAndContentHashAndCreatedAtAfter(Long jobId, String contentHash, LocalDateTime after);
long countByIpHashAndCreatedAtAfter(String ipHash, LocalDateTime after);
long countByUaHashAndCreatedAtAfter(String uaHash, LocalDateTime after);
/** 公开列表(含筛选):PUBLISHED 且审核通过;支持评分档/时间范围/未回复筛选 */
@Query("SELECT r FROM JobReview r"
+ " WHERE r.jobId = :jobId AND r.status = :status"
+ " AND r.moderationStatus IN :moderationStatuses"
+ " AND (:ratingType IS NULL OR"
+ " (:ratingType = 'GOOD' AND r.rating = 5)"
+ " OR (:ratingType = 'MEDIUM' AND r.rating IN (3,4))"
+ " OR (:ratingType = 'BAD' AND r.rating IN (1,2)))"
+ " AND (:createdFrom IS NULL OR r.createdAt >= :createdFrom)"
+ " AND (:createdTo IS NULL OR r.createdAt <= :createdTo)"
+ " AND (:unreplied = false OR NOT EXISTS"
+ " (SELECT 1 FROM CompanyReviewReply rr"
+ " WHERE rr.reviewId = r.id AND rr.moderationStatus = 'APPROVED'))"
+ " ORDER BY r.createdAt DESC")
Page<JobReview> findPublicReviews(@Param("jobId") Long jobId,
@Param("status") String status,
@Param("moderationStatuses") Collection<String> moderationStatuses,
@Param("ratingType") String ratingType,
@Param("createdFrom") LocalDateTime createdFrom,
@Param("createdTo") LocalDateTime createdTo,
@Param("unreplied") boolean unreplied,
Pageable pageable);
/** 管理端待审列表:PENDING,支持 jobId / riskLevel / 时间范围筛选 */
@Query("SELECT r FROM JobReview r WHERE r.status = 'PUBLISHED' AND r.moderationStatus = 'PENDING'"
+ " AND (:jobId IS NULL OR r.jobId = :jobId)"
+ " AND (:riskLevel IS NULL OR r.riskLevel = :riskLevel)"
+ " AND (:createdFrom IS NULL OR r.createdAt >= :createdFrom)"
+ " AND (:createdTo IS NULL OR r.createdAt <= :createdTo)")
Page<JobReview> findPendingModeration(@Param("jobId") Long jobId,
@Param("riskLevel") String riskLevel,
@Param("createdFrom") LocalDateTime createdFrom,
@Param("createdTo") LocalDateTime createdTo,
Pageable pageable);
}