基本功能已初步完善
This commit is contained in:
@@ -3,17 +3,21 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"xboard-go/internal/database"
|
||||
"xboard-go/internal/model"
|
||||
"xboard-go/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// --- Stat Extra ---
|
||||
|
||||
func AdminGetStatUser(c *gin.Context) {
|
||||
userIdStr := c.Query("user_id")
|
||||
params := getFetchParams(c)
|
||||
userIdStr := firstString(c.Query("user_id"), params["user_id"], params["id"])
|
||||
userId, _ := strconv.Atoi(userIdStr)
|
||||
if userId == 0 {
|
||||
Fail(c, http.StatusBadRequest, "user_id is required")
|
||||
@@ -46,16 +50,16 @@ func AdminPaymentSave(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
id := intFromAny(payload["id"])
|
||||
|
||||
|
||||
// Complex configuration usually stored as JSON
|
||||
configJson, _ := marshalJSON(payload["config"], true)
|
||||
|
||||
|
||||
values := map[string]any{
|
||||
"name": payload["name"],
|
||||
"payment": payload["payment"],
|
||||
"config": configJson,
|
||||
"notify_domain": payload["notify_domain"],
|
||||
"handling_fee_fixed": payload["handling_fee_fixed"],
|
||||
"name": payload["name"],
|
||||
"payment": payload["payment"],
|
||||
"config": configJson,
|
||||
"notify_domain": payload["notify_domain"],
|
||||
"handling_fee_fixed": payload["handling_fee_fixed"],
|
||||
"handling_fee_percent": payload["handling_fee_percent"],
|
||||
}
|
||||
|
||||
@@ -68,7 +72,9 @@ func AdminPaymentSave(c *gin.Context) {
|
||||
}
|
||||
|
||||
func AdminPaymentDrop(c *gin.Context) {
|
||||
var payload struct{ ID int `json:"id"` }
|
||||
var payload struct {
|
||||
ID int `json:"id"`
|
||||
}
|
||||
c.ShouldBindJSON(&payload)
|
||||
database.DB.Delete(&model.Payment{}, payload.ID)
|
||||
Success(c, true)
|
||||
@@ -85,7 +91,9 @@ func AdminPaymentShow(c *gin.Context) {
|
||||
}
|
||||
|
||||
func AdminPaymentSort(c *gin.Context) {
|
||||
var payload struct{ IDs []int `json:"ids"` }
|
||||
var payload struct {
|
||||
IDs []int `json:"ids"`
|
||||
}
|
||||
c.ShouldBindJSON(&payload)
|
||||
for i, id := range payload.IDs {
|
||||
database.DB.Model(&model.Payment{}).Where("id = ?", id).Update("sort", i)
|
||||
@@ -106,15 +114,15 @@ func AdminNoticeSave(c *gin.Context) {
|
||||
c.ShouldBindJSON(&payload)
|
||||
id := intFromAny(payload["id"])
|
||||
now := time.Now().Unix()
|
||||
|
||||
|
||||
values := map[string]any{
|
||||
"title": payload["title"],
|
||||
"content": payload["content"],
|
||||
"img_url": payload["img_url"],
|
||||
"tags": payload["tags"],
|
||||
"title": payload["title"],
|
||||
"content": payload["content"],
|
||||
"img_url": payload["img_url"],
|
||||
"tags": payload["tags"],
|
||||
"updated_at": now,
|
||||
}
|
||||
|
||||
|
||||
if id > 0 {
|
||||
database.DB.Model(&model.Notice{}).Where("id = ?", id).Updates(values)
|
||||
} else {
|
||||
@@ -125,7 +133,9 @@ func AdminNoticeSave(c *gin.Context) {
|
||||
}
|
||||
|
||||
func AdminNoticeDrop(c *gin.Context) {
|
||||
var payload struct{ ID int `json:"id"` }
|
||||
var payload struct {
|
||||
ID int `json:"id"`
|
||||
}
|
||||
c.ShouldBindJSON(&payload)
|
||||
database.DB.Delete(&model.Notice{}, payload.ID)
|
||||
Success(c, true)
|
||||
@@ -148,18 +158,30 @@ func AdminNoticeSort(c *gin.Context) {
|
||||
// --- Order Extra ---
|
||||
|
||||
func AdminOrderDetail(c *gin.Context) {
|
||||
var payload struct{ TradeNo string `json:"trade_no"` }
|
||||
var payload struct {
|
||||
ID int `json:"id"`
|
||||
TradeNo string `json:"trade_no"`
|
||||
}
|
||||
c.ShouldBindJSON(&payload)
|
||||
var order model.Order
|
||||
database.DB.Preload("Plan").Preload("Payment").Where("trade_no = ?", payload.TradeNo).First(&order)
|
||||
query := database.DB.Preload("Plan").Preload("Payment")
|
||||
if payload.TradeNo != "" {
|
||||
query = query.Where("trade_no = ?", payload.TradeNo)
|
||||
} else if payload.ID > 0 {
|
||||
query = query.Where("id = ?", payload.ID)
|
||||
}
|
||||
if err := query.First(&order).Error; err != nil {
|
||||
Fail(c, http.StatusNotFound, "order not found")
|
||||
return
|
||||
}
|
||||
Success(c, normalizeOrder(order))
|
||||
}
|
||||
|
||||
func AdminOrderAssign(c *gin.Context) {
|
||||
var payload struct {
|
||||
Email string `json:"email"`
|
||||
PlanID int `json:"plan_id"`
|
||||
Period string `json:"period"`
|
||||
Email string `json:"email"`
|
||||
PlanID int `json:"plan_id"`
|
||||
Period string `json:"period"`
|
||||
}
|
||||
c.ShouldBindJSON(&payload)
|
||||
// Logic to manually create/assign an order and mark as paid
|
||||
@@ -177,11 +199,22 @@ func AdminOrderUpdate(c *gin.Context) {
|
||||
// --- User Extra ---
|
||||
|
||||
func AdminUserResetSecret(c *gin.Context) {
|
||||
var payload struct{ ID int `json:"id"` }
|
||||
c.ShouldBindJSON(&payload)
|
||||
newUuid := "new-uuid-placeholder" // Generate actual UUID
|
||||
database.DB.Model(&model.User{}).Where("id = ?", payload.ID).Update("uuid", newUuid)
|
||||
Success(c, true)
|
||||
var payload struct {
|
||||
ID int `json:"id"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&payload); err != nil || payload.ID <= 0 {
|
||||
Fail(c, http.StatusBadRequest, "user id is required")
|
||||
return
|
||||
}
|
||||
newUUID := uuid.NewString()
|
||||
newToken := strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
if err := database.DB.Model(&model.User{}).
|
||||
Where("id = ?", payload.ID).
|
||||
Updates(map[string]any{"uuid": newUUID, "token": newToken}).Error; err != nil {
|
||||
Fail(c, http.StatusInternalServerError, "failed to reset secret")
|
||||
return
|
||||
}
|
||||
Success(c, newToken)
|
||||
}
|
||||
|
||||
func AdminUserSendMail(c *gin.Context) {
|
||||
@@ -190,8 +223,49 @@ func AdminUserSendMail(c *gin.Context) {
|
||||
Subject string `json:"subject"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
c.ShouldBindJSON(&payload)
|
||||
// Logic to send email
|
||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||
Fail(c, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
if payload.UserID <= 0 {
|
||||
Fail(c, http.StatusBadRequest, "user id is required")
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(payload.Subject) == "" {
|
||||
Fail(c, http.StatusBadRequest, "subject is required")
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(payload.Content) == "" {
|
||||
Fail(c, http.StatusBadRequest, "content is required")
|
||||
return
|
||||
}
|
||||
|
||||
var user model.User
|
||||
if err := database.DB.Select("email").Where("id = ?", payload.UserID).First(&user).Error; err != nil {
|
||||
Fail(c, http.StatusBadRequest, "user does not exist")
|
||||
return
|
||||
}
|
||||
|
||||
textBody := payload.Content
|
||||
htmlBody := ""
|
||||
if looksLikeHTML(payload.Content) {
|
||||
htmlBody = payload.Content
|
||||
}
|
||||
|
||||
if err := service.SendMailWithCurrentSettings(service.EmailMessage{
|
||||
To: []string{user.Email},
|
||||
Subject: payload.Subject,
|
||||
TextBody: textBody,
|
||||
HTMLBody: htmlBody,
|
||||
}); err != nil {
|
||||
Fail(c, http.StatusInternalServerError, "failed to send email: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
Success(c, true)
|
||||
}
|
||||
|
||||
func looksLikeHTML(value string) bool {
|
||||
value = strings.TrimSpace(value)
|
||||
return strings.Contains(value, "<") && strings.Contains(value, ">")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user