package handlers import ( "log/slog" "platform/web/auth" "platform/web/core" g "platform/web/globals" m "platform/web/models" q "platform/web/queries" s "platform/web/services" "time" "github.com/gofiber/fiber/v2" ) // PageTradeByAdmin 分页查询所有订单 func PageTradeByAdmin(c *fiber.Ctx) error { // 检查权限 _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeRead) if err != nil { return err } // 解析请求参数 req := new(PageTradeByAdminReq) if err := g.Validator.ParseBody(c, req); err != nil { return err } // 构建查询语句 do := q.Trade.Where() if req.UserPhone != nil { do = do.Where(q.User.As("User").Phone.Eq(*req.UserPhone)) } if req.InnerNo != nil { do = do.Where(q.Trade.InnerNo.Eq(*req.InnerNo)) } if req.OuterNo != nil { do = do.Where(q.Trade.OuterNo.Eq(*req.OuterNo)) } if req.Method != nil { do = do.Where(q.Trade.Method.Eq(*req.Method)) } if req.Platform != nil { do = do.Where(q.Trade.Platform.Eq(*req.Platform)) } if req.Status != nil { do = do.Where(q.Trade.Status.Eq(*req.Status)) } if req.CreatedAtStart != nil { do = do.Where(q.Trade.CreatedAt.Gte(req.CreatedAtStart.UTC())) } if req.CreatedAtEnd != nil { do = do.Where(q.Trade.CreatedAt.Lte(req.CreatedAtEnd.UTC())) } // 查询用户列表 list, total, err := q.Trade. Joins(q.Trade.User). Select( q.Trade.ALL, q.User.As("User").Phone.As("User__phone"), q.User.As("User").Name.As("User__name"), ). Where(do). Order(q.Trade.CreatedAt.Desc()). FindByPage(req.GetOffset(), req.GetLimit()) if err != nil { return err } // 返回结果 return c.JSON(core.PageResp{ List: list, Total: int(total), Page: req.GetPage(), Size: req.GetSize(), }) } type PageTradeByAdminReq struct { core.PageReq UserPhone *string `json:"user_phone,omitempty"` InnerNo *string `json:"inner_no,omitempty"` OuterNo *string `json:"outer_no,omitempty"` Method *int `json:"method,omitempty"` Platform *int `json:"platform,omitempty"` Status *int `json:"status,omitempty"` CreatedAtStart *time.Time `json:"created_at_start,omitempty"` CreatedAtEnd *time.Time `json:"created_at_end,omitempty"` } // PageTradeOfUserByAdmin 分页查询指定用户的订单 func PageTradeOfUserByAdmin(c *fiber.Ctx) error { // 检查权限 _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeReadOfUser) if err != nil { return err } // 解析请求参数 req := new(PageTradeOfUserByAdminReq) if err := g.Validator.ParseBody(c, req); err != nil { return err } // 构建查询语句 do := q.Trade.Where(q.Trade.UserID.Eq(req.UserID)) if req.InnerNo != nil { do = do.Where(q.Trade.InnerNo.Eq(*req.InnerNo)) } if req.OuterNo != nil { do = do.Where(q.Trade.OuterNo.Eq(*req.OuterNo)) } if req.Method != nil { do = do.Where(q.Trade.Method.Eq(*req.Method)) } if req.Platform != nil { do = do.Where(q.Trade.Platform.Eq(*req.Platform)) } if req.Status != nil { do = do.Where(q.Trade.Status.Eq(*req.Status)) } if req.CreatedAtStart != nil { do = do.Where(q.Trade.CreatedAt.Gte(req.CreatedAtStart.UTC())) } if req.CreatedAtEnd != nil { do = do.Where(q.Trade.CreatedAt.Lte(req.CreatedAtEnd.UTC())) } // 查询订单列表 list, total, err := q.Trade. Joins(q.Trade.User). Select( q.Trade.ALL, q.User.As("User").Phone.As("User__phone"), q.User.As("User").Name.As("User__name"), ). Where(do). Order(q.Trade.CreatedAt.Desc()). FindByPage(req.GetOffset(), req.GetLimit()) if err != nil { return err } // 返回结果 return c.JSON(core.PageResp{ List: list, Total: int(total), Page: req.GetPage(), Size: req.GetSize(), }) } type PageTradeOfUserByAdminReq struct { core.PageReq UserID int32 `json:"user_id" validate:"required"` InnerNo *string `json:"inner_no,omitempty"` OuterNo *string `json:"outer_no,omitempty"` Method *int `json:"method,omitempty"` Platform *int `json:"platform,omitempty"` Status *int `json:"status,omitempty"` CreatedAtStart *time.Time `json:"created_at_start,omitempty"` CreatedAtEnd *time.Time `json:"created_at_end,omitempty"` } // ============================================================ // 创建订单 func TradeCreate(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } if authCtx.User.IDType == m.UserIDTypeUnverified { return core.NewBizErr("请先实名认证后再购买") } // 解析请求参数 req := new(TradeCreateReq) if err := g.Validator.ParseBody(c, req); err != nil { return err } switch req.Type { case m.TradeTypePurchase: if req.Resource == nil { return core.NewBizErr("购买信息不能为空") } case m.TradeTypeRecharge: if req.Recharge == nil { return core.NewBizErr("充值信息不能为空") } } // 处理订单 var result *s.CreateTradeResult switch req.Type { case m.TradeTypePurchase: result, err = s.Trade.Create(authCtx.User, req.CreateTradeData, req.Resource) case m.TradeTypeRecharge: result, err = s.Trade.Create(authCtx.User, req.CreateTradeData, req.Recharge) } if err != nil { return core.NewServErr("处理购买产品信息失败", err) } return c.JSON(result) } type TradeCreateReq struct { *s.CreateTradeData Type m.TradeType `json:"type" validate:"required"` Resource *s.CreateResourceData `json:"resource,omitempty"` Recharge *s.UpdateBalanceData `json:"recharge,omitempty"` } // ============================================================ // 更新订单备注 func TradeUpdateRemarkByAdmin(c *fiber.Ctx) error { // 检查权限 _, err := auth.GetAuthCtx(c).PermitAdmin() if err != nil { return err } // 解析请求参数 var req TradeUpdateRemarkReq if err := g.Validator.ParseBody(c, &req); err != nil { return err } // 更新订单备注 err = s.Trade.UpdateRemark(req.TradeNo, req.Remark) if err != nil { return err } return c.SendStatus(fiber.StatusNoContent) } type TradeUpdateRemarkReq struct { TradeNo string `json:"trade_no" validate:"required"` Remark string `json:"remark"` } // ============================================================ // 完成订单 func TradeComplete(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 var req s.TradeRef if err := g.Validator.ParseBody(c, &req); err != nil { return err } // 检查订单状态 err = s.Trade.CompleteTrade(authCtx.User, &req) if err != nil { return err } return c.SendStatus(fiber.StatusNoContent) } // 管理员完成订单 func TradeCompleteByAdmin(c *fiber.Ctx) error { // 检查权限 _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeWriteComplete) if err != nil { return err } // 解析请求参数 var req struct { s.TradeRef UserID int32 `json:"user_id" validate:"required"` } if err := g.Validator.ParseBody(c, &req); err != nil { return err } // 获取用户信息 user, err := s.User.Get(q.Q, req.UserID) if err != nil { return err } // 完成订单 err = s.Trade.CompleteTrade(user, &req.TradeRef) if err != nil { return err } return c.SendStatus(fiber.StatusNoContent) } // 订单补余额 func TradeConvertByAdmin(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeWrite) if err != nil { return err } // 解析请求参数 var req s.TradeRef if err := g.Validator.ParseBody(c, &req); err != nil { return err } // 订单补余额 err = s.Trade.ConvertTradeToBalance(authCtx.Admin, &req) if err != nil { return err } return c.SendStatus(fiber.StatusNoContent) } // ============================================================ // 取消订单 func TradeCancel(c *fiber.Ctx) error { // 检查权限 _, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 req := new(s.TradeRef) if err := g.Validator.ParseBody(c, req); err != nil { return err } // 取消交易 err = s.Trade.CancelTrade(req) if err != nil && err != s.ErrTradeStatusIgnored { slog.Error("取消交易失败", "trade_no", req.TradeNo, "error", err) return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "取消交易失败"}) } return c.SendStatus(fiber.StatusNoContent) } // ============================================================ // 结束订单:完成或取消订单 func TradeFinish(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 var req s.TradeRef if err := g.Validator.ParseBody(c, &req); err != nil { return err } // 尝试取消交易 err = s.Trade.CancelTrade(&req) if err == s.ErrTradeStatusIgnored { // 尝试完成交易 err = s.Trade.CompleteTrade(authCtx.User, &req) if err != nil { return err } return c.JSON(map[string]m.TradeStatus{ "status": m.TradeStatusSuccess, }) } else if err != nil { return err } return c.JSON(map[string]m.TradeStatus{ "status": m.TradeStatusCanceled, }) } // ============================================================ // 检查订单 func TradeCheck(c *fiber.Ctx) error { _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeTradeRead) if err != nil { return err } // 解析请求参数 var req s.TradeRef if err := g.Validator.ParseBody(c, &req); err != nil { return err } // 检查订单状态 result, err := s.Trade.CheckTrade(&req) if err != nil { return err } return c.JSON(result) }