mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
dev day #89
This commit is contained in:
@@ -103,6 +103,8 @@ func (cc *CommentController) Unreact(c *gin.Context) {
|
||||
|
||||
// Admin: list all comments with filters
|
||||
func (cc *CommentController) AdminList(c *gin.Context) {
|
||||
// Ensure tables exist (best-effort)
|
||||
_ = cc.DB.AutoMigrate(&models.Comment{}, &models.CommentReport{}, &models.CommentReaction{})
|
||||
var items []models.Comment
|
||||
q := cc.DB.Preload("User").Model(&models.Comment{})
|
||||
if v := strings.TrimSpace(c.Query("status")); v != "" { q = q.Where("status = ?", v) }
|
||||
@@ -125,8 +127,21 @@ func (cc *CommentController) AdminList(c *gin.Context) {
|
||||
_ = cc.DB.Table("comment_reports").Select("comment_id, COUNT(*) as cnt").Where("comment_id IN ?", ids).Group("comment_id").Scan(&rows).Error
|
||||
for _, r := range rows { repCounts[r.CommentID] = r.Cnt }
|
||||
}
|
||||
// Compute admin likes (thumbs_up/like) per comment
|
||||
adminLiked := map[uint]bool{}
|
||||
if len(ids) > 0 {
|
||||
type al struct{ CommentID uint }
|
||||
var rows []al
|
||||
_ = cc.DB.Table("comment_reactions as cr").
|
||||
Select("cr.comment_id").
|
||||
Joins("JOIN users u ON u.id = cr.user_id").
|
||||
Where("cr.comment_id IN ? AND u.role = ? AND cr.type IN ?", ids, "admin", []string{"thumbs_up", "like"}).
|
||||
Group("cr.comment_id").
|
||||
Scan(&rows).Error
|
||||
for _, r := range rows { adminLiked[r.CommentID] = true }
|
||||
}
|
||||
out := make([]commentOutput, 0, len(items))
|
||||
for _, r := range items { co := toOutput(r); if v, ok := repCounts[r.ID]; ok { co.Reports = v }; out = append(out, co) }
|
||||
for _, r := range items { co := toOutput(r); if v, ok := repCounts[r.ID]; ok { co.Reports = v }; if adminLiked[r.ID] { co.AdminLiked = true }; out = append(out, co) }
|
||||
c.JSON(http.StatusOK, gin.H{"items": out, "total": total, "page": page, "page_size": size})
|
||||
}
|
||||
|
||||
@@ -216,6 +231,7 @@ type commentOutput struct {
|
||||
SpamScore float32 `json:"spam_score,omitempty"`
|
||||
SpamRules []string `json:"spam_rules,omitempty"`
|
||||
Reports int `json:"reports,omitempty"`
|
||||
AdminLiked bool `json:"admin_liked,omitempty"`
|
||||
}
|
||||
|
||||
type userSlim struct {
|
||||
@@ -273,14 +289,32 @@ func (cc *CommentController) GetComments(c *gin.Context) {
|
||||
if page < 1 { page = 1 }
|
||||
|
||||
var total int64
|
||||
q := cc.DB.Model(&models.Comment{}).Where("target_type = ? AND target_id = ? AND status = ?", targetType, targetID, "visible")
|
||||
// Visibility rules:
|
||||
// - Public/unauthenticated: only visible
|
||||
// - Authenticated non-admin: visible + own hidden (awaiting moderation)
|
||||
// - Admin: all
|
||||
role, _ := c.Get("userRole")
|
||||
uid, _ := c.Get("userID")
|
||||
var where string
|
||||
var args []interface{}
|
||||
if role == "admin" {
|
||||
where = "target_type = ? AND target_id = ?"
|
||||
args = []interface{}{targetType, targetID}
|
||||
} else if uid != nil {
|
||||
where = "target_type = ? AND target_id = ? AND (status = 'visible' OR (status = 'hidden' AND user_id = ?))"
|
||||
args = []interface{}{targetType, targetID, uid}
|
||||
} else {
|
||||
where = "target_type = ? AND target_id = ? AND status = 'visible'"
|
||||
args = []interface{}{targetType, targetID}
|
||||
}
|
||||
q := cc.DB.Model(&models.Comment{}).Where(where, args...)
|
||||
if err := q.Count(&total).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
|
||||
var rows []models.Comment
|
||||
if err := cc.DB.Preload("User").Where("target_type = ? AND target_id = ? AND status = ?", targetType, targetID, "visible").
|
||||
if err := cc.DB.Preload("User").Where(where, args...).
|
||||
Order("created_at ASC").
|
||||
Offset((page-1)*pageSize).Limit(pageSize).
|
||||
Find(&rows).Error; err != nil {
|
||||
@@ -316,6 +350,19 @@ func (cc *CommentController) GetComments(c *gin.Context) {
|
||||
for _, r := range rs { myReactions[r.CommentID] = r.Type }
|
||||
}
|
||||
}
|
||||
// Admin liked map
|
||||
adminLiked := map[uint]bool{}
|
||||
if len(ids) > 0 {
|
||||
type al struct{ CommentID uint }
|
||||
var rows []al
|
||||
_ = cc.DB.Table("comment_reactions as cr").
|
||||
Select("cr.comment_id").
|
||||
Joins("JOIN users u ON u.id = cr.user_id").
|
||||
Where("cr.comment_id IN ? AND u.role = ? AND cr.type IN ?", ids, "admin", []string{"thumbs_up", "like"}).
|
||||
Group("cr.comment_id").
|
||||
Scan(&rows).Error
|
||||
for _, r := range rows { adminLiked[r.CommentID] = true }
|
||||
}
|
||||
// Preload user profiles for username + avatar (prefer animated when available)
|
||||
type up struct{ UserID uint; AvatarURL string; AnimatedAvatarURL string; Username string }
|
||||
profByUser := map[uint]up{}
|
||||
@@ -337,6 +384,7 @@ func (cc *CommentController) GetComments(c *gin.Context) {
|
||||
}
|
||||
if rc, ok := reactionCounts[r.ID]; ok { co.Reactions = rc } else { co.Reactions = map[string]int{} }
|
||||
if myReactions != nil { if t, ok := myReactions[r.ID]; ok { co.MyReaction = t } }
|
||||
if adminLiked[r.ID] { co.AdminLiked = true }
|
||||
out = append(out, co)
|
||||
}
|
||||
|
||||
@@ -381,6 +429,18 @@ func (cc *CommentController) CreateComment(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if in.ParentID != nil {
|
||||
var parent models.Comment
|
||||
if err := cc.DB.First(&parent, *in.ParentID).Error; err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Rodičovský komentář nenalezen"})
|
||||
return
|
||||
}
|
||||
if parent.TargetType != in.TargetType || parent.TargetID != in.TargetID {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Rodičovský komentář neodpovídá cíli"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
userIDv, _ := c.Get("userID")
|
||||
userID := userIDv.(uint)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user