package web import ( "net/http" "strings" "videoweb/app/service/authser" "videoweb/app/service/rechargeser" "videoweb/pub/common/log" "videoweb/pub/common/useragent" "github.com/gin-gonic/gin" ) type buyPayBody struct { PackageID int64 `json:"packageId"` PayMode string `json:"payMode"` } // attachWalletFromGetInfo 登录态拉取 getInfo,刷新 cookie,并写入模板金币余额。 // 返回 true 表示注册账号会话失效,调用方应跳转登录。 func attachWalletFromGetInfo(c *gin.Context, data gin.H) bool { if data == nil || useragent.TokenFromRequest(c.Request) == "" { return false } env, user, err := authser.GetInfo(c) if err != nil { log.Error("wallet getInfo failed", log.E(err)) return false } if env != nil && authser.IsSessionExpiredCode(env.Code) { retry, needLogin := authser.OnSessionExpired(c, env.Code) if needLogin { return true } if retry { env, user, err = authser.GetInfo(c) if err != nil { log.Error("wallet getInfo retry failed", log.E(err)) return false } } } if env == nil || env.Code != 200 || user == nil { return false } authser.SetAuthCookies(c, user) data["userId"] = authser.FormatUserID(user.UserID) data["recharge"] = user.Recharge data["rechargeText"] = authser.FormatRecharge(user.Recharge) data["vipType"] = user.VipType data["showCardId"] = user.ShowCardID data["showCardName"] = strings.TrimSpace(user.ShowCardName) active := authser.IsActiveVipUser(user.VipType, user.CurrentVipExpire) data["isVip"] = active if active { data["vipLabel"] = authser.VipDisplayLabel(user.ShowCardName, user.VipType) data["vipExpireText"] = authser.FormatVipExpireText(user.CurrentVipExpire) } else { delete(data, "vipLabel") delete(data, "vipExpireText") } return false } // Deposit 金币与会员充值页 SSR:套餐列表 + 金币流水明细。 // Query tab=coin 时默认选中金币充值套餐。 func Deposit(c *gin.Context) { // 先补游客会话,保证可拉流水。 authser.EnsureGuestOnEnter(c) preferTab := routeOrQuery(c, "tab", "tab") if hasQuery(c, "tab") { target := "/deposit" if preferTab != "" { target += "/" + preferTab } target += "/" if redirectCanonical(c, target) { return } } raw := rechargeser.FetchPackageListOrEmpty(c) vm := rechargeser.BuildDepositPageVM(raw, preferTab) if useragent.TokenFromRequest(c.Request) != "" { list, code, err := rechargeser.FetchCoinTransList(c, 1, 20) if err != nil { retry, needLogin := authser.OnSessionExpired(c, code) if needLogin { RedirectToLogin(c) return } if retry { list, _, err = rechargeser.FetchCoinTransList(c, 1, 20) } if err != nil { log.Error("fetch coin trans list failed", log.E(err)) list = nil } } vm.AttachTxList(list) } data := gin.H{ "title": "金币与会员", "vipList": vm.VipList, "coinList": vm.CoinList, "payMethods": vm.PayMethods, "txList": vm.TxList, "preferTab": preferTab, } setNoIndex(data, false) if attachWalletFromGetInfo(c, data) { RedirectToLogin(c) return } HTMLOK(c, "deposit.html", data) } // CoinBuy 代理上游 POST /api/app/coin/buy。 func CoinBuy(c *gin.Context) { handleBuyPay(c, "coin") } // VipPay 代理上游 POST /api/app/vip/pay。 func VipPay(c *gin.Context) { handleBuyPay(c, "vip") } func handleBuyPay(c *gin.Context, kind string) { if useragent.TokenFromRequest(c.Request) == "" { c.JSON(http.StatusOK, gin.H{ "code": 401, "msg": "unauthorized", "tip": "请先登录后再支付", "data": nil, }) return } var body buyPayBody if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "code": 1001, "msg": "参数错误", "tip": "参数错误", "data": nil, }) return } body.PayMode = rechargeser.NormalizePayMode(body.PayMode) if body.PackageID <= 0 || body.PayMode == "" { c.JSON(http.StatusOK, gin.H{ "code": 1001, "msg": "参数错误", "tip": "请选择套餐和支付方式", "data": nil, }) return } req := rechargeser.BuyPayReq{ PackageID: body.PackageID, PayMode: body.PayMode, } var ( env *rechargeser.APIEnvelope[rechargeser.PayOrderResp] err error ) switch kind { case "coin": env, err = rechargeser.BuyCoin(c, req) default: env, err = rechargeser.VipPay(c, req) } if err != nil { log.Error("buy/pay upstream failed", log.E(err)) c.JSON(http.StatusOK, gin.H{ "code": 500, "msg": "pay failed", "tip": "发起支付失败,请稍后重试", "data": nil, }) return } if env != nil && TryJSONSessionRecover(c, env.Code) { switch kind { case "coin": env, err = rechargeser.BuyCoin(c, req) default: env, err = rechargeser.VipPay(c, req) } if err != nil { log.Error("buy/pay retry failed", log.E(err)) c.JSON(http.StatusOK, gin.H{ "code": 500, "msg": "pay failed", "tip": "发起支付失败,请稍后重试", "data": nil, }) return } } if env == nil || env.Code != 200 { tip := "发起支付失败" msg := "" code := 500 if env != nil { code = env.Code msg = env.Msg tip = firstNonEmpty(env.Tip, env.Msg, tip) } c.JSON(http.StatusOK, gin.H{ "code": code, "msg": msg, "tip": tip, "data": nil, }) return } payURL := strings.TrimSpace(env.Data.PayURL) if payURL == "" { c.JSON(http.StatusOK, gin.H{ "code": 500, "msg": "empty payUrl", "tip": "未获取到支付链接,请稍后重试", "data": nil, }) return } c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": firstNonEmpty(env.Msg, "success"), "tip": firstNonEmpty(env.Tip, "请完成支付"), "data": gin.H{ "isOpenNewBrowser": env.Data.IsOpenNewBrowser, "payUrl": payURL, "payUrlMode": env.Data.PayURLMode, "tradeNo": env.Data.TradeNo, }, }) }