113 lines
2.7 KiB
Go
113 lines
2.7 KiB
Go
|
package models
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"code.nonshy.com/nonshy/website/pkg/log"
|
||
|
)
|
||
|
|
||
|
// UserNote table where users can write private notes about each other.
|
||
|
type UserNote struct {
|
||
|
ID uint64 `gorm:"primaryKey"`
|
||
|
UserID uint64 `gorm:"index"` // author ID
|
||
|
AboutUserID uint64 `gorm:"index"` // target user ID
|
||
|
Message string
|
||
|
CreatedAt time.Time
|
||
|
UpdatedAt time.Time
|
||
|
}
|
||
|
|
||
|
// GetNoteBetweenUsers finds the existing note or creates an empty model if not found.
|
||
|
func GetNoteBetweenUsers(currentUser *User, user *User) *UserNote {
|
||
|
var (
|
||
|
note = &UserNote{}
|
||
|
result = DB.Model(note).Where(
|
||
|
"user_id = ? AND about_user_id = ?",
|
||
|
currentUser.ID, user.ID,
|
||
|
).First(¬e)
|
||
|
)
|
||
|
if result.Error != nil {
|
||
|
note = &UserNote{
|
||
|
UserID: currentUser.ID,
|
||
|
AboutUserID: user.ID,
|
||
|
}
|
||
|
}
|
||
|
return note
|
||
|
}
|
||
|
|
||
|
// CountNotesAboutUser returns the number of notes (the current user) has about the other user.
|
||
|
//
|
||
|
// For regular user, will return zero or one; for admins, will return the total count of notes
|
||
|
// left by any other users about this user.
|
||
|
func CountNotesAboutUser(currentUser *User, user *User) int64 {
|
||
|
var (
|
||
|
wheres = []string{}
|
||
|
placeholders = []interface{}{}
|
||
|
count int64
|
||
|
)
|
||
|
|
||
|
if currentUser.IsAdmin {
|
||
|
wheres = append(wheres, "about_user_id = ?")
|
||
|
placeholders = append(placeholders, user.ID)
|
||
|
} else {
|
||
|
wheres = append(wheres, "user_id = ? AND about_user_id = ?")
|
||
|
placeholders = append(placeholders, currentUser.ID, user.ID)
|
||
|
}
|
||
|
|
||
|
query := DB.Model(&UserNote{}).Where(
|
||
|
strings.Join(wheres, " AND "),
|
||
|
placeholders...,
|
||
|
).Count(&count)
|
||
|
if query.Error != nil {
|
||
|
log.Error("CountNotesAboutUser(%s, %s): %s", currentUser.Username, user.Username, query.Error)
|
||
|
}
|
||
|
|
||
|
return count
|
||
|
}
|
||
|
|
||
|
// PaginateUserNotes shows all notes written by users about the target user.
|
||
|
func PaginateUserNotes(user *User, pager *Pagination) ([]*UserNote, error) {
|
||
|
var (
|
||
|
notes = []*UserNote{}
|
||
|
wheres = []string{}
|
||
|
placeholders = []interface{}{}
|
||
|
)
|
||
|
|
||
|
wheres = append(wheres, "about_user_id = ?")
|
||
|
placeholders = append(placeholders, user.ID)
|
||
|
|
||
|
query := DB.Joins("JOIN users ON users.id = user_notes.user_id").Where(
|
||
|
strings.Join(wheres, " AND "),
|
||
|
placeholders...,
|
||
|
).Order(
|
||
|
"users.is_admin desc, " + pager.Sort,
|
||
|
)
|
||
|
|
||
|
query.Model(&UserNote{}).Count(&pager.Total)
|
||
|
|
||
|
result := query.Offset(
|
||
|
pager.GetOffset(),
|
||
|
).Limit(pager.PerPage).Find(¬es)
|
||
|
|
||
|
return notes, result.Error
|
||
|
}
|
||
|
|
||
|
// Save the note.
|
||
|
func (p *UserNote) Save() error {
|
||
|
if p.ID == 0 {
|
||
|
return DB.Create(p).Error
|
||
|
}
|
||
|
return DB.Save(p).Error
|
||
|
}
|
||
|
|
||
|
var ErrNoUserNoteToDelete = errors.New("you had no user note to delete")
|
||
|
|
||
|
// Delete the DB entry.
|
||
|
func (p *UserNote) Delete() error {
|
||
|
if p.ID == 0 {
|
||
|
return ErrNoUserNoteToDelete
|
||
|
}
|
||
|
return DB.Delete(p).Error
|
||
|
}
|