package web import ( "net/http" "strings" "videoweb/app/service/authser" "videoweb/pub/common/log" "github.com/gin-gonic/gin" ) type registerBody struct { AccountNo string `json:"accountNo"` Email string `json:"email"` Password string `json:"password"` AgentInviteCode string `json:"agentInviteCode"` DevID string `json:"devID"` Channel string `json:"channel"` } type loginBody struct { Account string `json:"account"` Password string `json:"password"` DevID string `json:"devID"` Channel string `json:"channel"` } // Register 代理上游注册(POST /api/app/auth/register),成功后写入登录 cookie。 // 请求头带游客 Authorization 时升级该游客;邮箱缺省时用账号生成占位邮箱。 func Register(c *gin.Context) { var body registerBody if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "code": 1001, "msg": "参数错误", "tip": "参数错误", "data": nil, }) return } body.AccountNo = strings.TrimSpace(body.AccountNo) body.Email = strings.TrimSpace(body.Email) body.AgentInviteCode = strings.TrimSpace(body.AgentInviteCode) body.DevID = strings.TrimSpace(body.DevID) body.Channel = authser.ResolveChannel(c, body.Channel) if body.AccountNo == "" || body.Password == "" { c.JSON(http.StatusOK, gin.H{ "code": 1001, "msg": "参数错误", "tip": "请填写账号和密码", "data": nil, }) return } // 上游 registerReq 要求 email;前端无邮箱时用账号生成唯一占位邮箱。 if body.Email == "" { body.Email = body.AccountNo + "@hgdj.local" } env, user, err := authser.Register(c, authser.RegisterReq{ AccountNo: body.AccountNo, Email: body.Email, Password: body.Password, AgentInviteCode: body.AgentInviteCode, DevID: body.DevID, Channel: body.Channel, }) if err != nil { log.Error("register upstream failed", log.E(err)) c.JSON(http.StatusOK, gin.H{ "code": 500, "msg": "register failed", "tip": "注册失败,请稍后重试", "data": nil, }) return } if env == nil || env.Code != 200 || user == nil { tip := "注册失败" msg := "" code := 500 if env != nil { code = env.Code msg = env.Msg if t := strings.TrimSpace(env.Tip); t != "" { tip = t } else if m := strings.TrimSpace(env.Msg); m != "" { tip = m } } c.JSON(http.StatusOK, gin.H{ "code": code, "msg": msg, "tip": tip, "data": nil, }) return } authser.SetAuthCookies(c, user) c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": firstNonEmptyAuth(env.Msg, "success"), "tip": firstNonEmptyAuth(env.Tip, "注册成功"), "data": user, }) } // Login 代理上游登录(POST /api/app/auth/login),成功后写入登录 cookie。 func Login(c *gin.Context) { var body loginBody if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "code": 1001, "msg": "参数错误", "tip": "参数错误", "data": nil, }) return } body.Account = strings.TrimSpace(body.Account) body.DevID = strings.TrimSpace(body.DevID) body.Channel = authser.ResolveChannel(c, body.Channel) if body.Account == "" || body.Password == "" { c.JSON(http.StatusOK, gin.H{ "code": 1001, "msg": "参数错误", "tip": "请填写账号和密码", "data": nil, }) return } env, user, err := authser.Login(c, authser.LoginReq{ Account: body.Account, Password: body.Password, DevID: body.DevID, Channel: body.Channel, }) if err != nil { log.Error("login upstream failed", log.E(err)) c.JSON(http.StatusOK, gin.H{ "code": 500, "msg": "login failed", "tip": "登录失败,请稍后重试", "data": nil, }) return } if env == nil || env.Code != 200 || user == nil { tip := "登录失败" msg := "" code := 500 if env != nil { code = env.Code msg = env.Msg if t := strings.TrimSpace(env.Tip); t != "" { tip = t } else if m := strings.TrimSpace(env.Msg); m != "" { tip = m } } c.JSON(http.StatusOK, gin.H{ "code": code, "msg": msg, "tip": tip, "data": nil, }) return } authser.SetAuthCookies(c, user) c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": firstNonEmptyAuth(env.Msg, "success"), "tip": firstNonEmptyAuth(env.Tip, "登录成功"), "data": user, }) } // Guest 代理上游游客登录,成功后写入登录 cookie。 // 对应 POST /api/app/auth/guest;需传 devID,上游要求 X-User-Agent / X-Real-IP(由 BFF 组装)。 func Guest(c *gin.Context) { var body struct { DevID string `json:"devID"` DeviceID string `json:"deviceId"` Mac string `json:"mac"` Channel string `json:"channel"` } if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "code": 1001, "msg": "参数错误", "tip": "参数错误", "data": nil, }) return } body.DevID = strings.TrimSpace(body.DevID) body.DeviceID = strings.TrimSpace(body.DeviceID) body.Mac = strings.TrimSpace(body.Mac) body.Channel = authser.ResolveChannel(c, body.Channel) if body.DevID == "" { c.JSON(http.StatusOK, gin.H{ "code": 1001, "msg": "参数错误", "tip": "缺少设备标识", "data": nil, }) return } if body.DeviceID == "" { body.DeviceID = body.DevID } env, user, err := authser.GuestLogin(c, authser.GuestLoginReq{ DevID: body.DevID, DeviceID: body.DeviceID, Mac: body.Mac, Channel: body.Channel, }) if err != nil { log.Error("guest login upstream failed", log.E(err)) c.JSON(http.StatusOK, gin.H{ "code": 500, "msg": "guest login failed", "tip": "游客登录失败,请稍后重试", "data": nil, }) return } if env == nil || env.Code != 200 || user == nil { tip := "游客登录失败" msg := "" code := 500 if env != nil { code = env.Code msg = env.Msg if t := strings.TrimSpace(env.Tip); t != "" { tip = t } else if m := strings.TrimSpace(env.Msg); m != "" { tip = m } } c.JSON(http.StatusOK, gin.H{ "code": code, "msg": msg, "tip": tip, "data": nil, }) return } authser.SetAuthCookies(c, user) c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": firstNonEmptyAuth(env.Msg, "success"), "tip": firstNonEmptyAuth(env.Tip, "游客登录成功"), "data": user, }) } // Logout 清除登录 cookie,并标记跳过紧接着的一次自动游客登录。 func Logout(c *gin.Context) { authser.ClearAuthCookies(c) authser.MarkGuestSkipAuto(c) c.JSON(http.StatusOK, gin.H{ "code": 200, "msg": "success", "tip": "已退出登录", "data": nil, }) } func firstNonEmptyAuth(values ...string) string { for _, v := range values { if strings.TrimSpace(v) != "" { return v } } return "" }