You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

337 lines
9.9 KiB

package user
import (
"context"
"yunyan/comm"
"yunyan/lego/sys/mysql"
"yunyan/lego/utils/container/id"
"yunyan/pb"
apple_auth "yunyan/sys/auth/apple"
facebook_auth "yunyan/sys/auth/facebook"
google_auth "yunyan/sys/auth/google"
wechat_auth "yunyan/sys/auth/wechat"
"yunyan/sys/ipinfo"
"fmt"
"time"
"firebase.google.com/go/v4/auth"
"github.com/golang-jwt/jwt/v4"
"golang.org/x/exp/rand"
)
// @Summary 登入接口
// @Description 根据登录类型实现登录操作
// @Tags User
// @Accept json
// @Produce json
// @Param user body pb.UserSginReq true "登录请求"
// @Success 200 {object} comm.HttpResult{data=pb.UserSginResp} "成功返回用户信息"
// @Router /api/home/user_sgin [post]
func (this *apiComp) Sgin(session comm.IUserSession, req *pb.UserSginReq) (resp *pb.UserSginResp, errdata *pb.ErrorData) {
var (
istestaccount bool
code string
apple_uuid string
wxinfo *wechat_auth.WeChatUserInfoResponse
googleinfo *auth.Token
facebookinfo *facebook_auth.FacebookTokenInfo
// firebaseinfo *auth.Token
ipdata *ipinfo.IPData
user *pb.DBUser
divices []*pb.DBUserDivice
tokenString string
err error
)
// this.module.Infof("登陆日志 options:%v req:%v", this.module.options, req)
switch req.Stype {
case pb.SginTyoe_Mail: //邮箱
if this.module.options.OpenTestAccount {
for _, account := range this.module.options.TestAccounts {
// this.module.Infof("登录日志 测试账号 account:%s req.Mail %s TestAccountPassword:%s Vcode:%s", account, req.Mail, this.module.options.TestAccountPassword, req.Vcode)
if account == req.Mail && this.module.options.TestAccountPassword == req.Vcode {
istestaccount = true
// this.module.Infof("登录日志 测试账号登录 account:%s", account)
break
}
}
}
if !istestaccount { //并非测试账号
if code, err = this.module.model.getCode(req.Mail); err != nil {
// this.module.Infof("登录日志 获取验证码失败 account:%s err:%v", req.Mail, err)
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
if code != req.Vcode {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ReqParameterError,
Message: "code is error",
}
return
}
}
if user, err = this.module.model.findformail(req.Mail); err != nil && err != mysql.ErrNoDocuments {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
case pb.SginTyoe_Phone: //手机
if this.module.options.OpenTestAccount {
for _, account := range this.module.options.TestAccounts {
if account == req.Phone && this.module.options.TestAccountPassword == req.Vcode {
istestaccount = true
break
}
}
}
if !istestaccount { //并非测试账号
if code, err = this.module.model.getCode(req.Phone); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
if code != req.Vcode {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ReqParameterError,
Message: "code is error",
}
return
}
}
if user, err = this.module.model.findforphone(req.Phone); err != nil && err != mysql.ErrNoDocuments {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
case pb.SginTyoe_WXChat: //微信
if wxinfo, err = wechat_auth.Auth(context.Background(), req.Ttoken); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ExceptionAccountVerification,
Message: err.Error(),
}
return
}
if user, err = this.module.model.findforwx(wxinfo.OpenID); err != nil && err != mysql.ErrNoDocuments {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
case pb.SginTyoe_Google: //微信
if googleinfo, err = google_auth.Auth(context.Background(), req.Ttoken); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ExceptionAccountVerification,
Message: err.Error(),
}
return
}
if user, err = this.module.model.findforgoogle(googleinfo.UID); err != nil && err != mysql.ErrNoDocuments {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
case pb.SginTyoe_FaceBook: //微信
if facebookinfo, err = facebook_auth.Auth(context.Background(), req.Ttoken); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ExceptionAccountVerification,
Message: err.Error(),
}
return
}
if user, err = this.module.model.findforfacebook(facebookinfo.UserID); err != nil && err != mysql.ErrNoDocuments {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
case pb.SginTyoe_Apple: //微信
if apple_uuid, err = apple_auth.Auth(context.Background(), req.Ttoken); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ExceptionAccountVerification,
Message: err.Error(),
}
return
}
if user, err = this.module.model.findforapple(apple_uuid); err != nil && err != mysql.ErrNoDocuments {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
case pb.SginTyoe_Tourists: //游客登录
// if req.Phonemac == "" {
// errdata = &pb.ErrorData{
// Code: pb.ErrorCode_ReqParameterError,
// Message: pb.ErrorCode_ReqParameterError.String(),
// }
// return
// }
// if user, err = this.module.model.findformac(req.Phonemac); err != nil && err != mysql.ErrNoDocuments {
// errdata = &pb.ErrorData{
// Code: pb.ErrorCode_DBError,
// Message: err.Error(),
// }
// return
// }
err = mysql.ErrNoDocuments
default:
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ReqParameterError,
Message: "stype is no support",
}
return
}
if err == mysql.ErrNoDocuments {
user = &pb.DBUser{
Uid: id.NewSnowflakeId(int64(this.options.UserGroup)),
Phone: req.Phone,
Mail: req.Mail,
Createtime: time.Now().Unix(),
Language: req.Language,
Phonemodel: req.Phonemodel,
Phonemac: req.Phonemac,
Avatar: req.Avatar,
Name: req.Name,
Channel: req.Channel,
Version: req.Version,
}
switch req.Stype {
case pb.SginTyoe_WXChat:
user.Wxopenid = wxinfo.OpenID
user.Name = wxinfo.Nickname
user.Avatar = wxinfo.HeadImgURL
case pb.SginTyoe_Google:
user.Googleopenid = googleinfo.UID
case pb.SginTyoe_FaceBook:
user.Facebookopenid = facebookinfo.UserID
case pb.SginTyoe_Apple:
user.Appleopenid = apple_uuid
}
// if user.Phone != "" {
// user.Phone = aes.AesEncryptCBC(user.Phone, this.options.CBCKey)
// }
// if user.Mail != "" {
// user.Mail = aes.AesEncryptCBC(user.Mail, this.options.CBCKey)
// }
if user.Name == "" {
user.Name = fmt.Sprintf("User_%d", rand.Intn(10000))
}
// user.Name = aes.AesEncryptCBC(user.Name, this.options.CBCKey)
// if user.Avatar != "" {
// user.Avatar = aes.AesEncryptCBC(user.Avatar, this.options.CBCKey)
// }
if err = this.module.model.add(user); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
// 新增用户埋点
if this.module.analyze != nil {
this.module.analyze.Report(&comm.StatEvent{Type: comm.StatEventRegister, Uid: user.Uid})
}
} else if user.State == pb.UserState_Disabled {
// 账号已被禁用,拒绝登录
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ExceptionAccountVerification,
Message: "account disabled",
}
return
} else if user.State == pb.UserState_Cancelled {
user.State = pb.UserState_Normal
user.Canceltime = 0
switch req.Stype {
case pb.SginTyoe_WXChat:
user.Wxopenid = wxinfo.OpenID
user.Name = wxinfo.Nickname
user.Avatar = wxinfo.HeadImgURL
case pb.SginTyoe_Google:
user.Googleopenid = googleinfo.UID
case pb.SginTyoe_FaceBook:
user.Facebookopenid = facebookinfo.UserID
case pb.SginTyoe_Apple:
user.Appleopenid = apple_uuid
}
if user.Name == "" {
user.Name = fmt.Sprintf("User_%d", rand.Intn(10000))
}
}
if istestaccount {
user.Vipexptime = time.Now().AddDate(1, 0, 0).Unix()
user.Aichattotalintegral = 1000000
user.Tradeintegral = 60 * 60 * 24 * 365
user.Tradetotalintegral = user.Tradeintegral
user.Meetintegral = 60 * 60 * 24 * 365
user.Meettotalintegral = user.Meetintegral
}
user.Lastsgintime = time.Now().Unix()
user.Channel = req.Channel
user.Version = req.Version
if ipdata, _ = ipinfo.GetIPInfo(session.GetIP()); ipdata != nil {
user.ContinentCode = ipdata.ContinentCode
user.CountryCode = ipdata.CountryCode
}
claims := &jwt.RegisteredClaims{
Issuer: "Earphone",
Subject: "Sgin",
// ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24)), // 24 hours expiration
NotBefore: jwt.NewNumericDate(time.Now()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: user.Uid,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
if tokenString, err = token.SignedString([]byte(this.options.TokenKey)); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_ReqParameterError,
Message: pb.ErrorCode_ReqParameterError.String(),
}
this.module.Errorln(err)
return
}
if err = this.module.model.save(user); err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
// 登录埋点
if this.module.analyze != nil {
// 登录归到用户最后绑定设备的产品/渠道商名下,渠道商后台才看得到自己带来的用户活跃。
this.module.analyze.Report(&comm.StatEvent{Type: comm.StatEventLogin, ProductId: user.Lastbindproductid, ChannelId: user.Lastbindchannelid, Uid: user.Uid})
}
divices, err = this.module.model.getDevices(user.Uid)
if err != nil {
errdata = &pb.ErrorData{
Code: pb.ErrorCode_DBError,
Message: err.Error(),
}
return
}
resp = &pb.UserSginResp{
Token: tokenString,
User: user,
Devices: divices,
}
return
}