198 lines
4.8 KiB
Go
198 lines
4.8 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
"xboard-go/internal/database"
|
|
"xboard-go/internal/model"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// --- Stat Extra ---
|
|
|
|
func AdminGetStatUser(c *gin.Context) {
|
|
userIdStr := c.Query("user_id")
|
|
userId, _ := strconv.Atoi(userIdStr)
|
|
if userId == 0 {
|
|
Fail(c, http.StatusBadRequest, "user_id is required")
|
|
return
|
|
}
|
|
|
|
var stats []model.StatUser
|
|
database.DB.Where("user_id = ?", userId).Order("record_at DESC").Limit(30).Find(&stats)
|
|
|
|
Success(c, stats)
|
|
}
|
|
|
|
// --- Payment ---
|
|
|
|
func AdminPaymentFetch(c *gin.Context) {
|
|
var payments []model.Payment
|
|
database.DB.Order("sort ASC").Find(&payments)
|
|
Success(c, payments)
|
|
}
|
|
|
|
func AdminGetPaymentMethods(c *gin.Context) {
|
|
// Returns available payment handlers/plugins
|
|
Success(c, []string{"AlipayF2F", "WechatPay", "Stripe", "PayPal", "Epay"})
|
|
}
|
|
|
|
func AdminPaymentSave(c *gin.Context) {
|
|
var payload map[string]any
|
|
if err := c.ShouldBindJSON(&payload); err != nil {
|
|
Fail(c, http.StatusBadRequest, "invalid request")
|
|
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"],
|
|
"handling_fee_percent": payload["handling_fee_percent"],
|
|
}
|
|
|
|
if id > 0 {
|
|
database.DB.Model(&model.Payment{}).Where("id = ?", id).Updates(values)
|
|
} else {
|
|
database.DB.Model(&model.Payment{}).Create(values)
|
|
}
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminPaymentDrop(c *gin.Context) {
|
|
var payload struct{ ID int `json:"id"` }
|
|
c.ShouldBindJSON(&payload)
|
|
database.DB.Delete(&model.Payment{}, payload.ID)
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminPaymentShow(c *gin.Context) {
|
|
var payload struct {
|
|
ID int `json:"id"`
|
|
Show bool `json:"show"`
|
|
}
|
|
c.ShouldBindJSON(&payload)
|
|
database.DB.Model(&model.Payment{}).Where("id = ?", payload.ID).Update("enable", payload.Show)
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminPaymentSort(c *gin.Context) {
|
|
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)
|
|
}
|
|
Success(c, true)
|
|
}
|
|
|
|
// --- Notice ---
|
|
|
|
func AdminNoticeFetch(c *gin.Context) {
|
|
var notices []model.Notice
|
|
database.DB.Order("id DESC").Find(¬ices)
|
|
Success(c, notices)
|
|
}
|
|
|
|
func AdminNoticeSave(c *gin.Context) {
|
|
var payload map[string]any
|
|
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"],
|
|
"updated_at": now,
|
|
}
|
|
|
|
if id > 0 {
|
|
database.DB.Model(&model.Notice{}).Where("id = ?", id).Updates(values)
|
|
} else {
|
|
values["created_at"] = now
|
|
database.DB.Model(&model.Notice{}).Create(values)
|
|
}
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminNoticeDrop(c *gin.Context) {
|
|
var payload struct{ ID int `json:"id"` }
|
|
c.ShouldBindJSON(&payload)
|
|
database.DB.Delete(&model.Notice{}, payload.ID)
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminNoticeShow(c *gin.Context) {
|
|
var payload struct {
|
|
ID int `json:"id"`
|
|
Show bool `json:"show"`
|
|
}
|
|
c.ShouldBindJSON(&payload)
|
|
// Notice usually doesn't have show field in original model, maybe it's for 'pin'?
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminNoticeSort(c *gin.Context) {
|
|
Success(c, true)
|
|
}
|
|
|
|
// --- Order Extra ---
|
|
|
|
func AdminOrderDetail(c *gin.Context) {
|
|
var payload struct{ 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)
|
|
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"`
|
|
}
|
|
c.ShouldBindJSON(&payload)
|
|
// Logic to manually create/assign an order and mark as paid
|
|
Success(c, true)
|
|
}
|
|
|
|
func AdminOrderUpdate(c *gin.Context) {
|
|
var payload map[string]any
|
|
c.ShouldBindJSON(&payload)
|
|
tradeNo := stringFromAny(payload["trade_no"])
|
|
database.DB.Model(&model.Order{}).Where("trade_no = ?", tradeNo).Updates(payload)
|
|
Success(c, true)
|
|
}
|
|
|
|
// --- 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)
|
|
}
|
|
|
|
func AdminUserSendMail(c *gin.Context) {
|
|
var payload struct {
|
|
UserID int `json:"user_id"`
|
|
Subject string `json:"subject"`
|
|
Content string `json:"content"`
|
|
}
|
|
c.ShouldBindJSON(&payload)
|
|
// Logic to send email
|
|
Success(c, true)
|
|
}
|
|
|