package handlers import ( "encoding/json" "fmt" "net/http" "strconv" "time" "github.com/gin-gonic/gin" "airwallex-admin/models" "airwallex-admin/services" ) func ListCards(c *gin.Context) { pageNum, _ := strconv.Atoi(c.DefaultQuery("page_num", "0")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) cardholderID := c.Query("cardholder_id") status := c.Query("status") result, err := services.ListCards(models.DB, pageNum, pageSize, cardholderID, status) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) return } c.JSON(http.StatusOK, result) } func CreateCard(c *gin.Context) { var body map[string]interface{} if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{"detail": "Invalid request body"}) return } // Check daily card limit dailyLimit := 100 if v := models.GetSetting(models.DB, "daily_card_limit"); v != "" { if n, err := strconv.Atoi(v); err == nil { dailyLimit = n } } todayStart := time.Now().UTC().Truncate(24 * time.Hour) var todayCount int64 models.DB.Model(&models.CardLog{}). Where("action = ? AND status = ? AND created_at >= ?", "create_card", "success", todayStart). Count(&todayCount) if int(todayCount) >= dailyLimit { c.JSON(http.StatusBadRequest, gin.H{"detail": "Daily card creation limit reached"}) return } username := c.GetString("username") reqData, _ := json.Marshal(body) result, err := services.CreateCard(models.DB, body) if err != nil { respData, _ := json.Marshal(map[string]string{"error": err.Error()}) models.DB.Create(&models.CardLog{ Action: "create_card", Status: "failed", Operator: username, RequestData: string(reqData), ResponseData: string(respData), }) c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) return } cardID, _ := result["card_id"].(string) cardholderID, _ := result["cardholder_id"].(string) respData, _ := json.Marshal(result) models.DB.Create(&models.CardLog{ CardID: cardID, CardholderID: cardholderID, Action: "create_card", Status: "success", Operator: username, RequestData: string(reqData), ResponseData: string(respData), }) models.DB.Create(&models.AuditLog{ Action: "create_card", ResourceType: "card", ResourceID: cardID, Operator: username, IPAddress: c.ClientIP(), Details: fmt.Sprintf("Created card %s", cardID), }) c.JSON(http.StatusOK, result) } func GetCard(c *gin.Context) { cardID := c.Param("id") result, err := services.GetCard(models.DB, cardID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) return } c.JSON(http.StatusOK, result) } func GetCardDetails(c *gin.Context) { cardID := c.Param("id") result, err := services.GetCardDetails(models.DB, cardID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) return } username := c.GetString("username") models.DB.Create(&models.AuditLog{ Action: "view_card_details", ResourceType: "card", ResourceID: cardID, Operator: username, IPAddress: c.ClientIP(), }) c.JSON(http.StatusOK, result) } func UpdateCard(c *gin.Context) { cardID := c.Param("id") var body map[string]interface{} if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{"detail": "Invalid request body"}) return } result, err := services.UpdateCard(models.DB, cardID, body) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"detail": err.Error()}) return } username := c.GetString("username") models.DB.Create(&models.AuditLog{ Action: "update_card", ResourceType: "card", ResourceID: cardID, Operator: username, IPAddress: c.ClientIP(), }) c.JSON(http.StatusOK, result) }