init: 初始化 AssetX 项目仓库

包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、
antdesign(管理后台)、landingpage(营销落地页)、
数据库 SQL 和配置文件。
This commit is contained in:
2026-03-27 11:26:43 +00:00
commit 2ee4553b71
634 changed files with 988255 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
package admin
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
appcfg "github.com/gothinkster/golang-gin-realworld-example-app/config"
"github.com/gothinkster/golang-gin-realworld-example-app/common"
"github.com/gothinkster/golang-gin-realworld-example-app/lending"
"github.com/gothinkster/golang-gin-realworld-example-app/models"
)
// ── Collateral Buyer Bot ───────────────────────────────────────────────────
func GetBuyerBotStatus(c *gin.Context) {
OK(c, lending.GetBuyerBotStatus())
}
func StartBuyerBot(c *gin.Context) {
cfg := appcfg.AppConfig
if cfg == nil {
Fail(c, http.StatusInternalServerError, "Configuration not loaded")
return
}
if cfg.CollateralBuyerPrivateKey == "" {
Fail(c, http.StatusBadRequest, "COLLATERAL_BUYER_PRIVATE_KEY not configured on server")
return
}
lending.StartCollateralBuyerBot(cfg)
OK(c, gin.H{"message": "Collateral buyer bot start signal sent"})
}
func StopBuyerBot(c *gin.Context) {
lending.StopCollateralBuyerBot()
OK(c, gin.H{"message": "Collateral buyer bot stop signal sent"})
}
func ListBuyRecords(c *gin.Context) {
db := common.GetDB()
p := ParsePagination(c)
query := db.Model(&models.CollateralBuyRecord{})
if v := c.Query("chain_id"); v != "" {
if id, err := strconv.Atoi(v); err == nil {
query = query.Where("chain_id = ?", id)
}
}
if v := c.Query("status"); v != "" {
query = query.Where("status = ?", v)
}
if v := c.Query("asset_addr"); v != "" {
query = query.Where("asset_addr = ?", v)
}
var total int64
query.Count(&total)
var records []models.CollateralBuyRecord
if err := query.Order("created_at DESC").Offset(p.Offset()).Limit(p.PageSize).Find(&records).Error; err != nil {
Fail(c, http.StatusInternalServerError, "Failed to fetch buy records")
return
}
OKList(c, records, total)
}
// GetLiquidationStatus returns the current liquidation bot status
func GetLiquidationStatus(c *gin.Context) {
status := lending.GetBotStatus()
OK(c, status)
}
// StartLiquidationBot starts the liquidation bot
func StartLiquidationBot(c *gin.Context) {
cfg := appcfg.AppConfig
if cfg == nil {
Fail(c, http.StatusInternalServerError, "Configuration not loaded")
return
}
if cfg.LiquidatorPrivateKey == "" {
Fail(c, http.StatusBadRequest, "LIQUIDATOR_PRIVATE_KEY not configured on server")
return
}
lending.StartLiquidationBot(cfg)
OK(c, gin.H{"message": "Liquidation bot start signal sent"})
}
// StopLiquidationBot stops the liquidation bot
func StopLiquidationBot(c *gin.Context) {
lending.StopLiquidationBot()
OK(c, gin.H{"message": "Liquidation bot stop signal sent"})
}
// ListLiquidationRecords returns paginated liquidation history
func ListLiquidationRecords(c *gin.Context) {
db := common.GetDB()
p := ParsePagination(c)
query := db.Model(&models.LiquidationRecord{})
if v := c.Query("chain_id"); v != "" {
if id, err := strconv.Atoi(v); err == nil {
query = query.Where("chain_id = ?", id)
}
}
if v := c.Query("status"); v != "" {
query = query.Where("status = ?", v)
}
if v := c.Query("liquidator_addr"); v != "" {
query = query.Where("liquidator_addr = ?", v)
}
var total int64
query.Count(&total)
var records []models.LiquidationRecord
if err := query.Order("created_at DESC").Offset(p.Offset()).Limit(p.PageSize).Find(&records).Error; err != nil {
Fail(c, http.StatusInternalServerError, "Failed to fetch liquidation records")
return
}
OKList(c, records, total)
}