diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRating.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRating.java new file mode 100644 index 00000000..92751d46 --- /dev/null +++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRating.java @@ -0,0 +1,50 @@ +package com.iflytek.skillhub.domain.social; + +import jakarta.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Table(name = "skill_rating", + uniqueConstraints = @UniqueConstraint(columnNames = {"skill_id", "user_id"})) +public class SkillRating { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "skill_id", nullable = false) + private Long skillId; + + @Column(name = "user_id", nullable = false) + private String userId; + + @Column(nullable = false) + private Short score; + + @Column(name = "created_at", nullable = false) + private LocalDateTime createdAt = LocalDateTime.now(); + + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt = LocalDateTime.now(); + + protected SkillRating() {} + + public SkillRating(Long skillId, String userId, short score) { + if (score < 1 || score > 5) throw new IllegalArgumentException("Score must be 1-5"); + this.skillId = skillId; + this.userId = userId; + this.score = score; + } + + public void updateScore(short newScore) { + if (newScore < 1 || newScore > 5) throw new IllegalArgumentException("Score must be 1-5"); + this.score = newScore; + this.updatedAt = LocalDateTime.now(); + } + + // getters + public Long getId() { return id; } + public Long getSkillId() { return skillId; } + public String getUserId() { return userId; } + public Short getScore() { return score; } + public LocalDateTime getCreatedAt() { return createdAt; } + public LocalDateTime getUpdatedAt() { return updatedAt; } +} diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java new file mode 100644 index 00000000..b29f5a4b --- /dev/null +++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillRatingRepository.java @@ -0,0 +1,10 @@ +package com.iflytek.skillhub.domain.social; + +import java.util.Optional; + +public interface SkillRatingRepository { + SkillRating save(SkillRating rating); + Optional findBySkillIdAndUserId(Long skillId, String userId); + double averageScoreBySkillId(Long skillId); + int countBySkillId(Long skillId); +} diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStar.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStar.java new file mode 100644 index 00000000..b87571c4 --- /dev/null +++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStar.java @@ -0,0 +1,34 @@ +package com.iflytek.skillhub.domain.social; + +import jakarta.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Table(name = "skill_star", + uniqueConstraints = @UniqueConstraint(columnNames = {"skill_id", "user_id"})) +public class SkillStar { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "skill_id", nullable = false) + private Long skillId; + + @Column(name = "user_id", nullable = false) + private String userId; + + @Column(name = "created_at", nullable = false) + private LocalDateTime createdAt = LocalDateTime.now(); + + protected SkillStar() {} + + public SkillStar(Long skillId, String userId) { + this.skillId = skillId; + this.userId = userId; + } + + // getters + public Long getId() { return id; } + public Long getSkillId() { return skillId; } + public String getUserId() { return userId; } + public LocalDateTime getCreatedAt() { return createdAt; } +} diff --git a/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java new file mode 100644 index 00000000..0cd9f1ab --- /dev/null +++ b/server/skillhub-domain/src/main/java/com/iflytek/skillhub/domain/social/SkillStarRepository.java @@ -0,0 +1,13 @@ +package com.iflytek.skillhub.domain.social; + +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface SkillStarRepository { + SkillStar save(SkillStar star); + Optional findBySkillIdAndUserId(Long skillId, String userId); + void delete(SkillStar star); + Page findByUserId(String userId, Pageable pageable); + long countBySkillId(Long skillId); +} diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java new file mode 100644 index 00000000..f60d8699 --- /dev/null +++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillRatingRepository.java @@ -0,0 +1,18 @@ +package com.iflytek.skillhub.infra.jpa; + +import com.iflytek.skillhub.domain.social.SkillRating; +import com.iflytek.skillhub.domain.social.SkillRatingRepository; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; +import java.util.Optional; + +@Repository +public interface JpaSkillRatingRepository extends JpaRepository, SkillRatingRepository { + Optional findBySkillIdAndUserId(Long skillId, String userId); + + @Query("SELECT COALESCE(AVG(r.score), 0) FROM SkillRating r WHERE r.skillId = :skillId") + double averageScoreBySkillId(Long skillId); + + int countBySkillId(Long skillId); +} diff --git a/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java new file mode 100644 index 00000000..e75201e5 --- /dev/null +++ b/server/skillhub-infra/src/main/java/com/iflytek/skillhub/infra/jpa/JpaSkillStarRepository.java @@ -0,0 +1,16 @@ +package com.iflytek.skillhub.infra.jpa; + +import com.iflytek.skillhub.domain.social.SkillStar; +import com.iflytek.skillhub.domain.social.SkillStarRepository; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +@Repository +public interface JpaSkillStarRepository extends JpaRepository, SkillStarRepository { + Optional findBySkillIdAndUserId(Long skillId, String userId); + Page findByUserId(String userId, Pageable pageable); + long countBySkillId(Long skillId); +}