package service import ( "context" "encoding/json" "errors" "fmt" "strconv" "strings" "time" "youngee_b_api/consts" "youngee_b_api/db" "youngee_b_api/model/gorm_model" "youngee_b_api/model/http_model" "youngee_b_api/model/redis_model" "youngee_b_api/model/system_model" "youngee_b_api/redis" "youngee_b_api/util" "github.com/sirupsen/logrus" ) var LoginAuth *loginAuth func LoginAuthInit(config *system_model.Session) { auth := new(loginAuth) auth.sessionTTL = time.Duration(config.TTL) * time.Minute LoginAuth = auth } type loginAuth struct { sessionTTL time.Duration } func (l *loginAuth) AuthToken(ctx context.Context, token string) (*redis_model.Auth, error) { phone, err := l.parseToken(ctx, token) if err != nil { logrus.Debug("token格式错误:%+v", token) return nil, err } auth, err := l.getSessionAuth(ctx, phone) if err != nil { logrus.Debug("获取session redis错误: token:%+v,err:%+v", token, err) return nil, err } if auth.Token != token { logrus.Debug("获取session time过期错误: token:%+v", token) return nil, errors.New("auth failed") } return auth, nil } // AuthCode 判断此手机号是否有账号存在 鉴定验证码 用户信息存入redis 并返回Token func (l *loginAuth) AuthCode(ctx context.Context, phone string, code string) (string, *http_model.CodeLoginData, error) { // 1. 验证码校验 vcode, err := l.getSessionCode(ctx, phone) if err != nil { return "", nil, err } fmt.Printf("缓存的验证码 vcode: %v,实际填入的 code:%v", vcode, code) if vcode != code { // 验证码错误 logrus.Debugf("[AuthCode] auth fail,phone:%+v", phone) return "验证码有误", nil, errors.New("auth fail") } // 2. 若无用户信息则注册 var userData *gorm_model.YounggeeUser user, err := db.GetUserByPhone(ctx, phone) fmt.Println("login_auth", user, err) if err != nil { // 数据库操作错误 return "", nil, err } else if user == nil { user, err := db.GetSubUserByPhone(ctx, phone) if user == nil { fmt.Println("子账号也不存在") // 账号不存在,则注册服务商与YG账号 _, err = Supplier.CreateSupplier(ctx, phone) if err != nil { return "服务商账号创建失败", nil, err } user, err = db.GetUserByPhone(ctx, phone) userData = user fmt.Println("login_auth", user, err) if err != nil { return "", nil, err } } else { userData = user } } else if user != nil { fmt.Println("是服务商主账号") userData = user } token := l.getToken(ctx, phone) var jobData gorm_model.YounggeeJob var accountData gorm_model.YounggeeSubAccount var supplierUser gorm_model.YoungeeSupplier var ifsuppplier int = 0 var ifsubaccount int = 0 // 3. 根据用户类型的不同追加信息返回前端 // 若为服务商用户 if string(userData.Role) == "6" { fmt.Println("服务商主账号") supplier, err := db.GetSupplierByUserID(ctx, userData.ID) supplierUser = *supplier ifsuppplier = 1 // fmt.Println(supplier) if err != nil { return "", nil, err } auth := &redis_model.Auth{ Phone: phone, ID: userData.ID, User: userData.User, Username: userData.Username, RealName: userData.RealName, Role: userData.Role, Email: userData.Email, Token: token, EnterpriseID: "32123", SupplierId: supplier.SupplierId, } if err := l.setSession(ctx, phone, auth); err != nil { fmt.Printf("setSession error\n") return "", nil, err } } else { // 若为服务商子账号 fmt.Printf("服务商子账号") subaccount, err := db.FindSubAccountByPhone(ctx, phone) accountData = *subaccount if err != nil { return "", nil, err } ifsubaccount = 1 auth := &redis_model.Auth{ Phone: phone, ID: userData.ID, User: userData.User, Username: userData.Username, RealName: userData.RealName, Role: userData.Role, Email: userData.Email, Token: token, SupplierId: subaccount.SupplierId, EnterpriseID: "32123", } job, err := db.FindJobByJobId(ctx, subaccount.JobId) jobData = *job if err := l.setSession(ctx, phone, auth); err != nil { fmt.Printf("setSession error\n") return "", nil, err } } var loginUserData http_model.CodeLoginData if ifsuppplier == 1 { loginUserData = http_model.CodeLoginData{ UserId: userData.ID, Token: token, Role: userData.Role, SubAccountId: 0, SupplierId: supplierUser.SupplierId, JobName: "主账号无岗位", EnterpriseId: "1", CommercialCenter: "1", CooperatePermission: "1", FinancialPermission: "1", CommercialManagement: "1", } } else if ifsubaccount == 1 { loginUserData = http_model.CodeLoginData{ UserId: userData.ID, Token: token, Role: userData.Role, SubAccountId: accountData.SubAccountId, JobName: jobData.JobName, SupplierId: accountData.SupplierId, EnterpriseId: accountData.EnterpriseId, CommercialCenter: jobData.CommercialCenter, CooperatePermission: jobData.CooperatePermission, FinancialPermission: jobData.FinancialPermission, CommercialManagement: jobData.CommercialManagement, } } fmt.Println("finish: ", loginUserData) return "", &loginUserData, nil } // func (l *loginAuth) AuthPassword(ctx context.Context, phone string, password string) (string, error) { // // 验证是否存在 // user, err := db.GetUserByPhone(ctx, phone) // if err != nil { // return "", err // } // // 验证正确性 // if user == nil || user.Role != consts.BRole || user.Password != l.encryptPassword(password) { // // 登录失败 // logrus.Debugf("[AuthPassword] auth fail,phone:%+v", phone) // return "", errors.New("auth fail") // } // token := l.getToken(ctx, phone) // auth := &redis_model.Auth{ // Phone: phone, // ID: user.ID, // User: user.User, // Username: user.Username, // RealName: user.RealName, // Role: user.Role, // Email: user.Email, // Token: token, // } // if err := l.setSession(ctx, phone, auth); err != nil { // return "", err // } // return token, nil // } func (l *loginAuth) setSession(ctx context.Context, phone string, auth *redis_model.Auth) error { if authJson, err := json.Marshal(auth); err == nil { err = redis.Set(ctx, l.getRedisKey(phone), string(authJson), l.sessionTTL) if err == nil { return err } } return nil } func (l *loginAuth) getSessionCode(ctx context.Context, phone string) (string, error) { value, err := redis.Get(ctx, l.getRedisKey(phone)) if err != nil { if err == consts.RedisNil { return "", fmt.Errorf("not found in redis,phone:%+v", phone) } return "", err } return value, nil } func (l *loginAuth) getSessionAuth(ctx context.Context, phone string) (*redis_model.Auth, error) { value, err := redis.Get(ctx, l.getRedisKey(phone)) if err != nil { if err == consts.RedisNil { return nil, fmt.Errorf("not found in redis,phone:%+v", phone) } return nil, err } auth := new(redis_model.Auth) if err = json.Unmarshal([]byte(value), auth); err != nil { return nil, err } return auth, nil } func (l *loginAuth) getToken(ctx context.Context, phone string) string { timeSeed := strconv.FormatInt(time.Now().Unix(), 10) token := phone + "." + timeSeed + "." + util.MD5(phone, timeSeed, consts.AuthSalt) return token } func (l *loginAuth) parseToken(ctx context.Context, token string) (string, error) { parts := strings.Split(token, ".") if len(parts) == 3 { phone := parts[0] timeSeed := parts[1] if parts[2] == util.MD5(phone, timeSeed, consts.AuthSalt) { return phone, nil } } return "", errors.New("token invalid") } func (l *loginAuth) encryptPassword(password string) string { return util.MD5(password) } func (l *loginAuth) getRedisKey(key string) string { return fmt.Sprintf("%s%s", consts.SessionRedisPrefix, key) } func (l *loginAuth) SubAccountAuthCode(ctx context.Context, phone string, code string) (string, error) { user, err := db.FindSubAccountByPhone(ctx, phone) phoneNumber := phone fmt.Println("login_auth", user, err) if err != nil { // 数据库错误 return "数据库错误", err } else if user == nil { // 账号不存在,则判断此手机号码是否被服务商主账号注册 user, err := db.GetUserByPhone(ctx, phoneNumber) if err != nil { // 数据库操作错误 return "", err } else if user == nil { // 没有被服务商主账户注册,则可以注册 vcode, err := l.getSessionCode(ctx, phoneNumber) if err != nil { return "session err", err } fmt.Printf("缓存的验证码 vcode: %v,实际填入的 code:%v", vcode, code) if vcode != code { // 验证码错误 logrus.Debugf("[AuthCode] auth fail,phone:%+v", phone) return "验证码有误", errors.New("auth fail") } return "1", err } else if string(user.Role) == "6" { if user.AuthStatus == 1 { // 被服务商主账户注册,未认证,则可以注册 vcode, err := l.getSessionCode(ctx, phoneNumber) if err != nil { return "session err", err } fmt.Printf("缓存的验证码 vcode: %v,实际填入的 code:%v", vcode, code) if vcode != code { // 验证码错误 logrus.Debugf("[AuthCode] auth fail,phone:%+v", phone) return "验证码有误", errors.New("auth fail") } return "1", err } else { return "已认证的主账号存在", errors.New("auth fail") } } } else if user != nil { // 子账号存在,则无法注册 logrus.Debugf("[AuthCode] auth fail,phone:%+v", phone) return "子账号存在", errors.New("auth fail") } return "", nil }