lv8girl!
This commit is contained in:
47
internal/repositories/comment.go
Normal file
47
internal/repositories/comment.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package repositories
|
||||
|
||||
import "lv8girl/internal/models"
|
||||
|
||||
type CommentRepository struct{}
|
||||
|
||||
func NewCommentRepository() *CommentRepository {
|
||||
return &CommentRepository{}
|
||||
}
|
||||
|
||||
func (r *CommentRepository) FindByPostID(postID uint) ([]models.Comment, error) {
|
||||
var comments []models.Comment
|
||||
err := DB.Preload("User").Where("post_id = ?", postID).Order("created_at DESC").Find(&comments).Error
|
||||
return comments, err
|
||||
}
|
||||
|
||||
func (r *CommentRepository) FindAll() ([]models.Comment, error) {
|
||||
var comments []models.Comment
|
||||
err := DB.Preload("User").Order("created_at DESC").Find(&comments).Error
|
||||
return comments, err
|
||||
}
|
||||
|
||||
func (r *CommentRepository) Create(comment *models.Comment) error {
|
||||
return DB.Create(comment).Error
|
||||
}
|
||||
|
||||
func (r *CommentRepository) Delete(id uint) error {
|
||||
return DB.Delete(&models.Comment{}, id).Error
|
||||
}
|
||||
|
||||
func (r *CommentRepository) Count() (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Comment{}).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *CommentRepository) CountByPostID(postID uint) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Comment{}).Where("post_id = ?", postID).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *CommentRepository) CountByUserID(userID uint) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Comment{}).Where("user_id = ?", userID).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
36
internal/repositories/db.go
Normal file
36
internal/repositories/db.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"lv8girl/internal/models"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
var DB *gorm.DB
|
||||
|
||||
func Init(databasePath string) error {
|
||||
var err error
|
||||
DB, err = gorm.Open(sqlite.Open(databasePath), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = DB.AutoMigrate(
|
||||
&models.User{},
|
||||
&models.Discussion{},
|
||||
&models.Comment{},
|
||||
&models.Like{},
|
||||
&models.PrivateMessage{},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
146
internal/repositories/discussion.go
Normal file
146
internal/repositories/discussion.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"lv8girl/internal/models"
|
||||
)
|
||||
|
||||
type DiscussionRepository struct{}
|
||||
|
||||
func NewDiscussionRepository() *DiscussionRepository {
|
||||
return &DiscussionRepository{}
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) FindByID(id uint) (*models.Discussion, error) {
|
||||
var discussion models.Discussion
|
||||
err := DB.Preload("User").First(&discussion, id).Error
|
||||
return &discussion, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) FindByIDWithStats(id uint) (*models.Discussion, int64, int64, error) {
|
||||
discussion, err := r.FindByID(id)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
var likeCount, commentCount int64
|
||||
DB.Model(&models.Like{}).Where("post_id = ?", id).Count(&likeCount)
|
||||
DB.Model(&models.Comment{}).Where("post_id = ?", id).Count(&commentCount)
|
||||
|
||||
return discussion, likeCount, commentCount, nil
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) FindApproved(limit int) ([]models.Discussion, error) {
|
||||
var discussions []models.Discussion
|
||||
err := DB.Preload("User").
|
||||
Where("status = ?", "approved").
|
||||
Order("created_at DESC").
|
||||
Limit(limit).
|
||||
Find(&discussions).Error
|
||||
return discussions, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) FindByUserID(userID uint) ([]models.Discussion, error) {
|
||||
var discussions []models.Discussion
|
||||
err := DB.Where("user_id = ? AND status = ?", userID, "approved").
|
||||
Order("created_at DESC").
|
||||
Find(&discussions).Error
|
||||
return discussions, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) FindPending() ([]models.Discussion, error) {
|
||||
var discussions []models.Discussion
|
||||
err := DB.Preload("User").
|
||||
Where("status = ?", "pending").
|
||||
Order("created_at DESC").
|
||||
Find(&discussions).Error
|
||||
return discussions, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) FindAll() ([]models.Discussion, error) {
|
||||
var discussions []models.Discussion
|
||||
err := DB.Preload("User").Order("created_at DESC").Find(&discussions).Error
|
||||
return discussions, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) Create(discussion *models.Discussion) error {
|
||||
return DB.Create(discussion).Error
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) Update(discussion *models.Discussion) error {
|
||||
return DB.Save(discussion).Error
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) UpdateStatus(id uint, status string) error {
|
||||
return DB.Model(&models.Discussion{}).Where("id = ?", id).Update("status", status).Error
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) IncrementViews(id uint) error {
|
||||
return DB.Model(&models.Discussion{}).Where("id = ?", id).
|
||||
UpdateColumn("views", gorm.Expr("views + ?", 1)).Error
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) Delete(id uint) error {
|
||||
return DB.Delete(&models.Discussion{}, id).Error
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) Count() (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Discussion{}).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) CountByStatus(status string) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Discussion{}).Where("status = ?", status).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) CountByUserID(userID uint) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Discussion{}).Where("user_id = ? AND status = ?", userID, "approved").Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
type PostListItem struct {
|
||||
ID uint
|
||||
Title string
|
||||
Content string
|
||||
Username string
|
||||
Avatar string
|
||||
UserID uint
|
||||
LikeCount int64
|
||||
CommentCount int64
|
||||
Views int
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (r *DiscussionRepository) GetPostList(limit int) ([]PostListItem, error) {
|
||||
discussions, err := r.FindApproved(limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var posts []PostListItem
|
||||
for _, d := range discussions {
|
||||
var likeCount, commentCount int64
|
||||
DB.Model(&models.Like{}).Where("post_id = ?", d.ID).Count(&likeCount)
|
||||
DB.Model(&models.Comment{}).Where("post_id = ?", d.ID).Count(&commentCount)
|
||||
|
||||
posts = append(posts, PostListItem{
|
||||
ID: d.ID,
|
||||
Title: d.Title,
|
||||
Content: d.Content,
|
||||
Username: d.User.Username,
|
||||
Avatar: d.User.Avatar,
|
||||
UserID: d.User.ID,
|
||||
LikeCount: likeCount,
|
||||
CommentCount: commentCount,
|
||||
Views: d.Views,
|
||||
CreatedAt: d.CreatedAt,
|
||||
})
|
||||
}
|
||||
return posts, nil
|
||||
}
|
||||
37
internal/repositories/like.go
Normal file
37
internal/repositories/like.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package repositories
|
||||
|
||||
import "lv8girl/internal/models"
|
||||
|
||||
type LikeRepository struct{}
|
||||
|
||||
func NewLikeRepository() *LikeRepository {
|
||||
return &LikeRepository{}
|
||||
}
|
||||
|
||||
func (r *LikeRepository) FindByPostAndUser(postID, userID uint) (*models.Like, error) {
|
||||
var like models.Like
|
||||
err := DB.Where("post_id = ? AND user_id = ?", postID, userID).First(&like).Error
|
||||
return &like, err
|
||||
}
|
||||
|
||||
func (r *LikeRepository) Exists(postID, userID uint) bool {
|
||||
var count int64
|
||||
DB.Model(&models.Like{}).Where("post_id = ? AND user_id = ?", postID, userID).Count(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
func (r *LikeRepository) Create(like *models.Like) error {
|
||||
return DB.Create(like).Error
|
||||
}
|
||||
|
||||
func (r *LikeRepository) Count() (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Like{}).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *LikeRepository) CountByPostID(postID uint) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.Like{}).Where("post_id = ?", postID).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
69
internal/repositories/message.go
Normal file
69
internal/repositories/message.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"lv8girl/internal/models"
|
||||
)
|
||||
|
||||
type MessageRepository struct{}
|
||||
|
||||
func NewMessageRepository() *MessageRepository {
|
||||
return &MessageRepository{}
|
||||
}
|
||||
|
||||
func (r *MessageRepository) FindByID(id uint) (*models.PrivateMessage, error) {
|
||||
var msg models.PrivateMessage
|
||||
err := DB.First(&msg, id).Error
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
func (r *MessageRepository) Create(message *models.PrivateMessage) error {
|
||||
return DB.Create(message).Error
|
||||
}
|
||||
|
||||
func (r *MessageRepository) MarkAsRead(id uint) error {
|
||||
return DB.Model(&models.PrivateMessage{}).Where("id = ?", id).Update("is_read", true).Error
|
||||
}
|
||||
|
||||
func (r *MessageRepository) CountUnread(userID uint) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.PrivateMessage{}).
|
||||
Where("to_user_id = ? AND is_read = ?", userID, false).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *MessageRepository) FindConversations(userID uint) ([]models.PrivateMessage, error) {
|
||||
var messages []models.PrivateMessage
|
||||
err := DB.Where("from_user_id = ? OR to_user_id = ?", userID, userID).
|
||||
Order("created_at DESC").
|
||||
Find(&messages).Error
|
||||
return messages, err
|
||||
}
|
||||
|
||||
func (r *MessageRepository) FindLastMessage(userID, otherUserID uint) (*models.PrivateMessage, error) {
|
||||
var msg models.PrivateMessage
|
||||
err := DB.Where(
|
||||
"(from_user_id = ? AND to_user_id = ?) OR (from_user_id = ? AND to_user_id = ?)",
|
||||
userID, otherUserID, otherUserID, userID,
|
||||
).Order("created_at DESC").First(&msg).Error
|
||||
return &msg, err
|
||||
}
|
||||
|
||||
func (r *MessageRepository) CountUnreadFromUser(fromUserID, toUserID uint) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.PrivateMessage{}).
|
||||
Where("from_user_id = ? AND to_user_id = ? AND is_read = ?", fromUserID, toUserID, false).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
type ConversationSummary struct {
|
||||
UserID uint
|
||||
Username string
|
||||
Avatar string
|
||||
LastMsg string
|
||||
Time time.Time
|
||||
Unread int64
|
||||
}
|
||||
123
internal/repositories/user.go
Normal file
123
internal/repositories/user.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"lv8girl/internal/models"
|
||||
)
|
||||
|
||||
type UserRepository struct{}
|
||||
|
||||
func NewUserRepository() *UserRepository {
|
||||
return &UserRepository{}
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindByID(id uint) (*models.User, error) {
|
||||
var user models.User
|
||||
err := DB.First(&user, id).Error
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindByUsernameOrEmail(login string) (*models.User, error) {
|
||||
var user models.User
|
||||
err := DB.Where("username = ? OR email = ?", login, login).First(&user).Error
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindByUsername(username string) (*models.User, error) {
|
||||
var user models.User
|
||||
err := DB.Where("username = ?", username).First(&user).Error
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindByEmail(email string) (*models.User, error) {
|
||||
var user models.User
|
||||
err := DB.Where("email = ?", email).First(&user).Error
|
||||
return &user, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) ExistsByUsernameOrEmail(username, email string) bool {
|
||||
var count int64
|
||||
DB.Model(&models.User{}).Where("username = ? OR email = ?", username, email).Count(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
func (r *UserRepository) Create(user *models.User) error {
|
||||
return DB.Create(user).Error
|
||||
}
|
||||
|
||||
func (r *UserRepository) Update(user *models.User) error {
|
||||
return DB.Save(user).Error
|
||||
}
|
||||
|
||||
func (r *UserRepository) UpdateField(id uint, field string, value interface{}) error {
|
||||
return DB.Model(&models.User{}).Where("id = ?", id).Update(field, value).Error
|
||||
}
|
||||
|
||||
func (r *UserRepository) UpdateLastActive(id uint) error {
|
||||
now := time.Now()
|
||||
return r.UpdateField(id, "last_active", now)
|
||||
}
|
||||
|
||||
func (r *UserRepository) Delete(id uint) error {
|
||||
return DB.Delete(&models.User{}, id).Error
|
||||
}
|
||||
|
||||
func (r *UserRepository) Count() (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.User{}).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) CountOnline() (int64, error) {
|
||||
var count int64
|
||||
fiveMinutesAgo := time.Now().Add(-5 * time.Minute)
|
||||
err := DB.Model(&models.User{}).Where("last_active > ?", fiveMinutesAgo).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) CountByRole(role string) (int64, error) {
|
||||
var count int64
|
||||
err := DB.Model(&models.User{}).Where("role = ?", role).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindPending() ([]models.User, error) {
|
||||
var users []models.User
|
||||
err := DB.Where("status = ?", "pending").Order("created_at ASC").Find(&users).Error
|
||||
return users, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindAll() ([]models.User, error) {
|
||||
var users []models.User
|
||||
err := DB.Order("id").Find(&users).Error
|
||||
return users, err
|
||||
}
|
||||
|
||||
func (r *UserRepository) HashPassword(password string) (string, error) {
|
||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func (r *UserRepository) CheckPassword(password, hash string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) CreateAdminIfNotExists() error {
|
||||
var count int64
|
||||
DB.Model(&models.User{}).Where("role = ?", "admin").Count(&count)
|
||||
if count == 0 {
|
||||
passwordHash, _ := r.HashPassword("admin123")
|
||||
admin := models.User{
|
||||
Username: "admin",
|
||||
Email: "admin@lv8girl.local",
|
||||
PasswordHash: passwordHash,
|
||||
Role: "admin",
|
||||
Status: "approved",
|
||||
}
|
||||
return DB.Create(&admin).Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user