优化目录结构

This commit is contained in:
WilliamColton
2025-08-03 01:27:28 +08:00
parent d63081955e
commit c08723574d
222 changed files with 2 additions and 25 deletions

View File

@@ -0,0 +1,50 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
/** Generic activity entity. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "activities")
public class Activity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
private String icon;
private String content;
@Column(name = "start_time", nullable = false)
@CreationTimestamp
private LocalDateTime startTime;
@Column(name = "end_time")
private LocalDateTime endTime;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ActivityType type = ActivityType.NORMAL;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "activity_participants",
joinColumns = @JoinColumn(name = "activity_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<User> participants = new HashSet<>();
@Column(nullable = false)
private boolean ended = false;
}

View File

@@ -0,0 +1,7 @@
package com.openisle.model;
/** Activity type enumeration. */
public enum ActivityType {
NORMAL,
MILK_TEA
}

View File

@@ -0,0 +1,31 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDate;
/** Daily count of AI markdown formatting usage for a user. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "ai_format_usage",
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "use_date"}))
public class AiFormatUsage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@Column(name = "use_date", nullable = false)
private LocalDate useDate;
@Column(nullable = false)
private int count;
}

View File

@@ -0,0 +1,29 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "categories")
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@Column(nullable = false)
private String icon;
@Column
private String smallIcon;
@Column(name = "description", nullable = false)
private String description;
}

View File

@@ -0,0 +1,41 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "comments")
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, columnDefinition = "TEXT")
private String content;
@CreationTimestamp
@Column(nullable = false, updatable = false,
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)")
private LocalDateTime createdAt;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "author_id")
private User author;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "post_id")
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Comment parent;
}

View File

@@ -0,0 +1,10 @@
package com.openisle.model;
/**
* Sort options for comments.
*/
public enum CommentSort {
NEWEST,
OLDEST,
MOST_INTERACTIONS
}

View File

@@ -0,0 +1,27 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/** Subscription to a comment for replies notifications. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "comment_subscriptions",
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "comment_id"}))
public class CommentSubscription {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "comment_id")
private Comment comment;
}

View File

@@ -0,0 +1,41 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.HashSet;
import java.util.Set;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "drafts", uniqueConstraints = {
@UniqueConstraint(columnNames = {"author_id"})
})
public class Draft {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@Column(columnDefinition = "TEXT")
private String content;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "author_id")
private User author;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private Category category;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "draft_tags",
joinColumns = @JoinColumn(name = "draft_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new HashSet<>();
}

View File

@@ -0,0 +1,37 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDate;
/** Daily experience gain counts for a user. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "experience_logs",
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "log_date"}))
public class ExperienceLog {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@Column(name = "log_date", nullable = false)
private LocalDate logDate;
@Column(name = "post_count", nullable = false)
private int postCount;
@Column(name = "comment_count", nullable = false)
private int commentCount;
@Column(name = "reaction_count", nullable = false)
private int reactionCount;
}

View File

@@ -0,0 +1,26 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* Image entity tracking COS image reference counts.
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "images")
public class Image {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 512)
private String url;
@Column(nullable = false)
private long refCount = 0;
}

View File

@@ -0,0 +1,61 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime;
/**
* Entity representing a user notification.
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "notifications")
public class Notification {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private NotificationType type;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "comment_id")
private Comment comment;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_user_id")
private User fromUser;
@Enumerated(EnumType.STRING)
@Column(name = "reaction_type")
private ReactionType reactionType;
@Column(length = 1000)
private String content;
@Column
private Boolean approved;
@Column(name = "is_read", nullable = false)
private boolean read = false;
@CreationTimestamp
@Column(nullable = false, updatable = false,
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)")
private LocalDateTime createdAt;
}

View File

@@ -0,0 +1,37 @@
package com.openisle.model;
/**
* Types of user notifications.
*/
public enum NotificationType {
/** Someone viewed your post */
POST_VIEWED,
/** Someone replied to your post or comment */
COMMENT_REPLY,
/** Someone reacted to your post or comment */
REACTION,
/** A new post is waiting for review */
POST_REVIEW_REQUEST,
/** Your post under review was approved or rejected */
POST_REVIEWED,
/** A subscribed post received a new comment */
POST_UPDATED,
/** Someone subscribed to your post */
POST_SUBSCRIBED,
/** Someone unsubscribed from your post */
POST_UNSUBSCRIBED,
/** Someone you follow published a new post */
FOLLOWED_POST,
/** Someone started following you */
USER_FOLLOWED,
/** Someone unfollowed you */
USER_UNFOLLOWED,
/** A user you subscribe to created a post or comment */
USER_ACTIVITY,
/** A user requested registration approval */
REGISTER_REQUEST,
/** A user redeemed an activity reward */
ACTIVITY_REDEEM,
/** You were mentioned in a post or comment */
MENTION
}

View File

@@ -0,0 +1,7 @@
package com.openisle.model;
public enum PasswordStrength {
LOW,
MEDIUM,
HIGH
}

View File

@@ -0,0 +1,65 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.util.HashSet;
import java.util.Set;
import com.openisle.model.Tag;
import java.time.LocalDateTime;
/**
* Post entity representing an article posted by a user.
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "posts")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false, columnDefinition = "TEXT")
private String content;
@CreationTimestamp
@Column(nullable = false, updatable = false,
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)")
private LocalDateTime createdAt;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "author_id")
private User author;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private Category category;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "post_tags",
joinColumns = @JoinColumn(name = "post_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private java.util.Set<Tag> tags = new java.util.HashSet<>();
@Column(nullable = false)
private long views = 0;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private PostStatus status = PostStatus.PUBLISHED;
@Column
private LocalDateTime pinnedAt;
}

View File

@@ -0,0 +1,32 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDateTime;
/** Record of a user reading a post. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "post_reads",
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "post_id"}))
public class PostRead {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "post_id")
private Post post;
@Column(name = "last_read_at")
private LocalDateTime lastReadAt;
}

View File

@@ -0,0 +1,10 @@
package com.openisle.model;
/**
* Status of a post during its lifecycle.
*/
public enum PostStatus {
PUBLISHED,
PENDING,
REJECTED
}

View File

@@ -0,0 +1,27 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/** Subscription to a post for update notifications. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "post_subscriptions",
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "post_id"}))
public class PostSubscription {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "post_id")
private Post post;
}

View File

@@ -0,0 +1,9 @@
package com.openisle.model;
/**
* Application-wide article publish mode.
*/
public enum PublishMode {
DIRECT,
REVIEW
}

View File

@@ -0,0 +1,40 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime;
/**
* Entity storing a browser push subscription for a user.
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "push_subscriptions")
public class PushSubscription {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@Column(nullable = false, length = 512)
private String endpoint;
@Column(nullable = false, length = 256)
private String p256dh;
@Column(nullable = false, length = 256)
private String auth;
@CreationTimestamp
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt;
}

View File

@@ -0,0 +1,46 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
/**
* Reaction entity representing a user's reaction to a post or comment.
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "reactions",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"user_id", "post_id", "type"}),
@UniqueConstraint(columnNames = {"user_id", "comment_id", "type"})
})
public class Reaction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private ReactionType type;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "comment_id")
private Comment comment;
@CreationTimestamp
@Column(nullable = false, updatable = false,
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)")
private java.time.LocalDateTime createdAt;
}

View File

@@ -0,0 +1,19 @@
package com.openisle.model;
/**
* Enum of possible reaction types for posts and comments.
*/
public enum ReactionType {
LIKE,
DISLIKE,
RECOMMEND,
ANGRY,
FLUSHED,
STAR_STRUCK,
ROFL,
HOLDING_BACK_TEARS,
MIND_BLOWN,
POOP,
CLOWN,
SKULL
}

View File

@@ -0,0 +1,9 @@
package com.openisle.model;
/**
* Application-wide user registration mode.
*/
public enum RegisterMode {
DIRECT,
WHITELIST
}

View File

@@ -0,0 +1,6 @@
package com.openisle.model;
public enum Role {
ADMIN,
USER
}

View File

@@ -0,0 +1,45 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime;
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "tags")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@Column
private String icon;
@Column
private String smallIcon;
@Column(name = "description", nullable = false)
private String description;
@Column(nullable = false)
private boolean approved = true;
@CreationTimestamp
@Column(nullable = false, updatable = false,
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)")
private LocalDateTime createdAt;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "creator_id")
private User creator;
}

View File

@@ -0,0 +1,64 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDateTime;
import com.openisle.model.Role;
/**
* Simple user entity with basic fields and a role.
*/
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String password;
@Column(nullable = false)
private boolean verified = false;
private String verificationCode;
private String passwordResetCode;
private String avatar;
@Column(nullable = false)
private int experience = 0;
@Column(length = 1000)
private String introduction;
@Column(length = 1000)
private String registerReason;
@Column(nullable = false)
private boolean approved = true;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role = Role.USER;
@CreationTimestamp
@Column(nullable = false, updatable = false,
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)")
private LocalDateTime createdAt;
}

View File

@@ -0,0 +1,27 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/** Following relationship between users. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "user_subscriptions",
uniqueConstraints = @UniqueConstraint(columnNames = {"subscriber_id", "target_id"}))
public class UserSubscription {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "subscriber_id")
private User subscriber;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "target_id")
private User target;
}

View File

@@ -0,0 +1,28 @@
package com.openisle.model;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDate;
/** Daily visit record for a user. */
@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "user_visits",
uniqueConstraints = @UniqueConstraint(columnNames = {"user_id", "visit_date"}))
public class UserVisit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id")
private User user;
@Column(name = "visit_date", nullable = false)
private LocalDate visitDate;
}