mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
hot fix #1
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -62,6 +64,16 @@ func NewEngagementController(db *gorm.DB, es email.EmailService) *EngagementCont
|
||||
return &EngagementController{DB: db, Email: es}
|
||||
}
|
||||
|
||||
// genRewardSKU generates a short uppercase code like RWD-1A2B3C4D
|
||||
func genRewardSKU() string {
|
||||
b := make([]byte, 4)
|
||||
if _, err := rand.Read(b); err == nil {
|
||||
return "RWD-" + strings.ToUpper(hex.EncodeToString(b))
|
||||
}
|
||||
// Fallback to time-based base36 suffix
|
||||
return "RWD-" + strings.ToUpper(strconv.FormatInt(time.Now().UnixNano()%2176782336, 36))
|
||||
}
|
||||
|
||||
// Admin: adjust points for a user (positive or negative)
|
||||
// POST /api/v1/admin/engagement/adjust { user_id, delta, reason?, meta? }
|
||||
func (ec *EngagementController) AdminAdjustPoints(c *gin.Context) {
|
||||
@@ -536,7 +548,6 @@ func (ec *EngagementController) GetAchievements(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"achievements": items, "counters": gin.H{"comments": commentCount, "votes": voteCount, "newsletter": hasNewsletter}})
|
||||
}
|
||||
|
||||
// Admin: list rewards
|
||||
// GET /api/v1/admin/engagement/rewards
|
||||
func (ec *EngagementController) AdminListRewards(c *gin.Context) {
|
||||
var items []models.RewardItem
|
||||
@@ -579,6 +590,28 @@ func (ec *EngagementController) AdminListRewards(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to load rewards"})
|
||||
return
|
||||
}
|
||||
// Backfill missing SKU for merch_physical items
|
||||
for i := range items {
|
||||
if strings.EqualFold(strings.TrimSpace(items[i].Type), "merch_physical") {
|
||||
md := items[i].Metadata
|
||||
var skuVal string
|
||||
if md != nil {
|
||||
if v, ok := md["sku"]; ok {
|
||||
if s, ok2 := v.(string); ok2 {
|
||||
skuVal = strings.TrimSpace(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
if strings.TrimSpace(skuVal) == "" {
|
||||
if md == nil {
|
||||
md = datatypes.JSONMap{}
|
||||
}
|
||||
md["sku"] = genRewardSKU()
|
||||
_ = ec.DB.Model(&models.RewardItem{}).Where("id = ?", items[i].ID).Update("metadata", md).Error
|
||||
items[i].Metadata = md
|
||||
}
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"items": items})
|
||||
}
|
||||
|
||||
@@ -611,6 +644,20 @@ func (ec *EngagementController) AdminCreateReward(c *gin.Context) {
|
||||
if body.Metadata != nil {
|
||||
item.Metadata = body.Metadata
|
||||
}
|
||||
// Ensure SKU is auto-generated for merch_physical when missing/empty
|
||||
if strings.EqualFold(strings.TrimSpace(item.Type), "merch_physical") {
|
||||
if item.Metadata == nil {
|
||||
item.Metadata = datatypes.JSONMap{}
|
||||
}
|
||||
if v, ok := item.Metadata["sku"]; !ok {
|
||||
item.Metadata["sku"] = genRewardSKU()
|
||||
} else {
|
||||
s, _ := v.(string)
|
||||
if strings.TrimSpace(s) == "" {
|
||||
item.Metadata["sku"] = genRewardSKU()
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := ec.DB.Create(&item).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create reward"})
|
||||
return
|
||||
@@ -686,8 +733,55 @@ func (ec *EngagementController) AdminUpdateReward(c *gin.Context) {
|
||||
if body.Active != nil {
|
||||
updates["active"] = *body.Active
|
||||
}
|
||||
// Determine target type after potential change
|
||||
targetType := existing.Type
|
||||
if body.Type != nil {
|
||||
targetType = strings.TrimSpace(*body.Type)
|
||||
}
|
||||
if body.Metadata != nil {
|
||||
updates["metadata"] = body.Metadata
|
||||
// Merge existing metadata with new to preserve fields like auto-generated sku
|
||||
merged := map[string]interface{}{}
|
||||
if existing.Metadata != nil {
|
||||
for k, v := range existing.Metadata {
|
||||
merged[k] = v
|
||||
}
|
||||
}
|
||||
for k, v := range body.Metadata {
|
||||
merged[k] = v
|
||||
}
|
||||
if strings.EqualFold(strings.TrimSpace(targetType), "merch_physical") {
|
||||
if v, ok := merged["sku"]; !ok {
|
||||
merged["sku"] = genRewardSKU()
|
||||
} else {
|
||||
s, _ := v.(string)
|
||||
if strings.TrimSpace(s) == "" {
|
||||
merged["sku"] = genRewardSKU()
|
||||
}
|
||||
}
|
||||
}
|
||||
updates["metadata"] = merged
|
||||
} else {
|
||||
// If type is merch_physical and existing metadata lacks sku, add it
|
||||
if strings.EqualFold(strings.TrimSpace(targetType), "merch_physical") {
|
||||
needSKU := true
|
||||
if existing.Metadata != nil {
|
||||
if v, ok := existing.Metadata["sku"]; ok {
|
||||
if s, ok2 := v.(string); ok2 && strings.TrimSpace(s) != "" {
|
||||
needSKU = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if needSKU {
|
||||
merged := map[string]interface{}{}
|
||||
if existing.Metadata != nil {
|
||||
for k, v := range existing.Metadata {
|
||||
merged[k] = v
|
||||
}
|
||||
}
|
||||
merged["sku"] = genRewardSKU()
|
||||
updates["metadata"] = merged
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(updates) == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "No changes"})
|
||||
|
||||
Reference in New Issue
Block a user