Просмотр исходного кода

✨ feat(topup): Admin-wide topup listing and route reorganization

Allow administrators to view all platform topup orders and streamline admin-only routes.

Frontend
- TopupHistoryModal: dynamically switch endpoint by role
  - Admin → GET /api/user/topup (all orders)
  - Non-admin → GET /api/user/topup/self (own orders)
- Use shared utils `isAdmin()`; keep logic centralized and DRY
- Minor UI: set admin action button theme to outline for clarity

Backend
- model/topup.go: add GetAllTopUps(pageInfo) with pagination (ordered by id desc)
- controller/topup.go: add GetAllTopUps handler returning PageInfo response
- router/api-router.go:
  - Add admin route GET /api/user/topup (AdminAuth)
  - Move POST /api/user/topup/complete to adminRoute (keeps path stable, consolidates admin endpoints)

Security/Behavior
- Admin-only endpoints now reside under the admin route group with AdminAuth
- No behavior change for regular users; no schema changes

Affected files
- model/topup.go
- controller/topup.go
- router/api-router.go
- web/src/components/topup/modals/TopupHistoryModal.jsx
Apple\Apple 5 месяцев назад
Родитель
Сommit
2389dbafc5
4 измененных файлов с 50 добавлено и 4 удалено
  1. 15 0
      controller/topup.go
  2. 29 0
      model/topup.go
  3. 2 1
      router/api-router.go
  4. 4 3
      web/src/components/topup/modals/TopupHistoryModal.jsx

+ 15 - 0
controller/topup.go

@@ -330,6 +330,21 @@ func GetUserTopUps(c *gin.Context) {
 	common.ApiSuccess(c, pageInfo)
 }
 
+// GetAllTopUps 管理员获取全平台充值记录
+func GetAllTopUps(c *gin.Context) {
+	pageInfo := common.GetPageQuery(c)
+
+	topups, total, err := model.GetAllTopUps(pageInfo)
+	if err != nil {
+		common.ApiError(c, err)
+		return
+	}
+
+	pageInfo.SetTotal(int(total))
+	pageInfo.SetItems(topups)
+	common.ApiSuccess(c, pageInfo)
+}
+
 type AdminCompleteTopupRequest struct {
 	TradeNo string `json:"trade_no"`
 }

+ 29 - 0
model/topup.go

@@ -136,6 +136,35 @@ func GetUserTopUps(userId int, pageInfo *common.PageInfo) (topups []*TopUp, tota
 	return topups, total, nil
 }
 
+// GetAllTopUps 获取全平台的充值记录(管理员使用)
+func GetAllTopUps(pageInfo *common.PageInfo) (topups []*TopUp, total int64, err error) {
+	tx := DB.Begin()
+	if tx.Error != nil {
+		return nil, 0, tx.Error
+	}
+	defer func() {
+		if r := recover(); r != nil {
+			tx.Rollback()
+		}
+	}()
+
+	if err = tx.Model(&TopUp{}).Count(&total).Error; err != nil {
+		tx.Rollback()
+		return nil, 0, err
+	}
+
+	if err = tx.Order("id desc").Limit(pageInfo.GetPageSize()).Offset(pageInfo.GetStartIdx()).Find(&topups).Error; err != nil {
+		tx.Rollback()
+		return nil, 0, err
+	}
+
+	if err = tx.Commit().Error; err != nil {
+		return nil, 0, err
+	}
+
+	return topups, total, nil
+}
+
 // ManualCompleteTopUp 管理员手动完成订单并给用户充值
 func ManualCompleteTopUp(tradeNo string) error {
 	if tradeNo == "" {

+ 2 - 1
router/api-router.go

@@ -80,7 +80,6 @@ func SetApiRouter(router *gin.Engine) {
 				selfRoute.POST("/stripe/pay", middleware.CriticalRateLimit(), controller.RequestStripePay)
 				selfRoute.POST("/stripe/amount", controller.RequestStripeAmount)
 				selfRoute.POST("/aff_transfer", controller.TransferAffQuota)
-				selfRoute.POST("/topup/complete", middleware.AdminAuth(), controller.AdminCompleteTopUp)
 				selfRoute.PUT("/setting", controller.UpdateUserSetting)
 
 				// 2FA routes
@@ -95,6 +94,8 @@ func SetApiRouter(router *gin.Engine) {
 			adminRoute.Use(middleware.AdminAuth())
 			{
 				adminRoute.GET("/", controller.GetAllUsers)
+				adminRoute.GET("/topup", controller.GetAllTopUps)
+				adminRoute.POST("/topup/complete", controller.AdminCompleteTopUp)
 				adminRoute.GET("/search", controller.SearchUsers)
 				adminRoute.GET("/:id", controller.GetUser)
 				adminRoute.POST("/", controller.CreateUser)

+ 4 - 3
web/src/components/topup/modals/TopupHistoryModal.jsx

@@ -63,9 +63,10 @@ const TopupHistoryModal = ({ visible, onCancel, t }) => {
   const loadTopups = async (currentPage, currentPageSize) => {
     setLoading(true);
     try {
-      const res = await API.get(
-        `/api/user/topup/self?p=${currentPage}&page_size=${currentPageSize}`,
-      );
+      const endpoint = isAdmin()
+        ? `/api/user/topup?p=${currentPage}&page_size=${currentPageSize}`
+        : `/api/user/topup/self?p=${currentPage}&page_size=${currentPageSize}`;
+      const res = await API.get(endpoint);
       const { success, message, data } = res.data;
       if (success) {
         setTopups(data.items || []);