Files
assetx/webapp-back/admin/assets.go
default 2ee4553b71 init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、
antdesign(管理后台)、landingpage(营销落地页)、
数据库 SQL 和配置文件。
2026-03-27 11:26:43 +00:00

128 lines
3.6 KiB
Go

package admin
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/gothinkster/golang-gin-realworld-example-app/common"
"github.com/gothinkster/golang-gin-realworld-example-app/models"
)
func ListAssets(c *gin.Context) {
db := common.GetDB()
p := ParsePagination(c)
query := db.Model(&models.Asset{})
if v := c.Query("name"); v != "" {
query = query.Where("name LIKE ?", "%"+v+"%")
}
if v := c.Query("asset_code"); v != "" {
query = query.Where("asset_code LIKE ?", "%"+v+"%")
}
if v := c.Query("category"); v != "" {
query = query.Where("category = ?", v)
}
if v := c.Query("is_active"); v != "" {
query = query.Where("is_active = ?", v == "true")
}
var total int64
query.Count(&total)
var items []models.Asset
if err := query.Order("id DESC").Offset(p.Offset()).Limit(p.PageSize).Find(&items).Error; err != nil {
Fail(c, http.StatusInternalServerError, "Failed to fetch assets")
return
}
OKList(c, items, total)
}
func GetAsset(c *gin.Context) {
db := common.GetDB()
var item models.Asset
if err := db.First(&item, c.Param("id")).Error; err != nil {
Fail(c, http.StatusNotFound, "Asset not found")
return
}
OK(c, item)
}
func CreateAsset(c *gin.Context) {
db := common.GetDB()
var item models.Asset
if err := BindJSONFlexTime(c, &item); err != nil {
Fail(c, http.StatusBadRequest, err.Error())
return
}
item.ID = 0
// 合约地址唯一性校验(非空才校验)
if item.ContractAddress != "" {
var conflict models.Asset
if err := db.Where("contract_address = ?", item.ContractAddress).First(&conflict).Error; err == nil {
Fail(c, http.StatusConflict, "合约地址已被资产「"+conflict.Name+"」使用,请检查后重试")
return
}
}
now := time.Now()
if item.CreatedAt.IsZero() {
item.CreatedAt = now
}
item.UpdatedAt = now
if err := db.Create(&item).Error; err != nil {
Fail(c, http.StatusInternalServerError, err.Error())
return
}
LogOp(c, "create", "asset", "create_asset", &item.ID, item)
OK(c, item)
}
func UpdateAsset(c *gin.Context) {
db := common.GetDB()
var existing models.Asset
if err := db.First(&existing, c.Param("id")).Error; err != nil {
Fail(c, http.StatusNotFound, "Asset not found")
return
}
var item models.Asset
if err := BindJSONFlexTime(c, &item); err != nil {
Fail(c, http.StatusBadRequest, err.Error())
return
}
item.ID = existing.ID
// 合约地址唯一性校验(非空且与原值不同时校验)
if item.ContractAddress != "" && item.ContractAddress != existing.ContractAddress {
var conflict models.Asset
if err := db.Where("contract_address = ? AND id != ?", item.ContractAddress, existing.ID).First(&conflict).Error; err == nil {
Fail(c, http.StatusConflict, "合约地址已被资产「"+conflict.Name+"」使用,请检查后重试")
return
}
}
if existing.CreatedAt.IsZero() {
item.CreatedAt = time.Now()
} else {
item.CreatedAt = existing.CreatedAt
}
if err := db.Save(&item).Error; err != nil {
Fail(c, http.StatusInternalServerError, err.Error())
return
}
LogOp(c, "update", "asset", "update_asset", &item.ID, item)
OK(c, item)
}
func DeleteAsset(c *gin.Context) {
db := common.GetDB()
var item models.Asset
if err := db.First(&item, c.Param("id")).Error; err != nil {
Fail(c, http.StatusNotFound, "Asset not found")
return
}
if err := db.Delete(&item).Error; err != nil {
Fail(c, http.StatusInternalServerError, err.Error())
return
}
LogOp(c, "delete", "asset", "delete_asset", &item.ID, nil)
OK(c, gin.H{"message": "deleted"})
}