Initial commit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
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,
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user