package service import ( "context" "encoding/base64" "errors" "gadmin/config" "gadmin/internal/admin/forms" "gadmin/internal/admin/library/feishu" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "gadmin/utility/serializer" "gadmin/utility/token" "github.com/gin-gonic/gin" jsoniter "github.com/json-iterator/go" "github.com/larksuite/oapi-sdk-go/v3/core" "github.com/larksuite/oapi-sdk-go/v3/service/authen/v1" "github.com/sirupsen/logrus" "gorm.io/gorm" "strings" "time" ) var FeiShu = new(feishuService) type feishuService struct{} func (s *feishuService) FeiShuUserLogin(c *gin.Context) serializer.Response { q := query.Use(config.AdminDB).AdminUser //encodeToken := token.GetAuthorization(c) //if encodeToken != "" { // bytesT, err := base64.URLEncoding.DecodeString(encodeToken) // if err != nil { // logrus.Warningf("middleware base64.URLEncoding.DecodeString:%+v", err.Error()) // return serializer.CheckLogin() // } // t := string(bytesT) // tokenKey := config.GetTokenKey(t) // if config.TokenRedis.Exists(tokenKey).Val() == 0 { // return serializer.CheckLogin() // } // userStr := config.TokenRedis.Get(tokenKey).Val() // // claims := new(token.UserClaims) // if err := jsoniter.UnmarshalFromString(userStr, claims); err != nil { // return serializer.CheckLogin() // } // // // 查询登录token是否有效 // key := config.GetUserTokenKey(claims.ID) // tokenCTStr := config.TokenRedis.HGet(key, t).Val() // tokenCreateTime, err := strconv.Atoi(tokenCTStr) // if err != nil { // logrus.Warningf("middleware config.LogRedis.HGet:%+v", err.Error()) // return serializer.CheckLogin() // } // tokenCT := time.Unix(int64(tokenCreateTime), 0) // // if tokenCT.Before(time.Now().Add(-config.TokenExpireTime)) { // return serializer.CheckLogin() // } // // u, err := q.Where(q.ID.Eq(claims.ID)).First() // if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { // return serializer.Err(2, "", err) // } // if u.Status != 1 { // return serializer.ParamErr("账号已被禁用", nil) // } // user := &token.UserClaims{ // ID: u.ID, // UserName: u.UserName, // RoleId: int64(u.RoleID), // Avatar: u.Avatar, // Nickname: u.Nickname, // AccessToken: t, // } // userStr, _ = jsoniter.MarshalToString(user) // // config.TokenRedis.HSet(key, t, time.Now().Unix()) // config.TokenRedis.Expire(key, time.Hour*12) // // config.TokenRedis.Set(tokenKey, userStr, time.Hour*12) // // return serializer.Suc(forms.UserLoginRes{ // ID: u.ID, // UserName: u.UserName, // Nickname: u.Nickname, // Status: u.Status, // Avatar: u.Avatar, // Token: encodeToken, // }) //} code := c.Query("code") if code == "" { return serializer.ParamErr("code is empty", nil) } feishuUserInfo, err := s.GetFeiShuUserByCode(code) if err != nil { return serializer.Err(1, "", err) } if feishuUserInfo == nil { return serializer.Err(1, "获取用户信息失败", nil) } u, err := q.Where(q.FeishuUnionID.Eq(*feishuUserInfo.UnionId)).First() if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return serializer.Err(2, "", err) } if u == nil { // 不存在,创建 u = &model.AdminUser{ UserName: *feishuUserInfo.Name, Nickname: *feishuUserInfo.Name, Avatar: *feishuUserInfo.AvatarUrl, //Mobile: *feishuUserInfo.Mobile, FeishuUnionID: *feishuUserInfo.UnionId, CreatedAt: time.Now(), } if err = q.WithContext(context.Background()).Create(u); err != nil { return serializer.DBErr(err.Error(), err) } return serializer.Err(9999, "注册成功,请联系管理员分配权限!", nil) } if u.Status != 1 { return serializer.ParamErr("账号已被禁用", nil) } if u.RoleID == 0 { return serializer.Err(9999, "请联系管理员分配权限!", nil) } t := token.GenerateTokenUsingUUID() // 记录登录token key := config.GetUserTokenKey(u.ID) config.TokenRedis.HSet(key, t, time.Now().Unix()) config.TokenRedis.Expire(key, time.Hour*12) tokenKey := config.GetTokenKey(t) user := &token.UserClaims{ ID: u.ID, UserName: u.UserName, RoleId: int64(u.RoleID), Avatar: u.Avatar, Nickname: u.Nickname, AccessToken: t, } userStr, err := jsoniter.MarshalToString(user) if err != nil { return serializer.Err(1, "", err) } config.TokenRedis.Set(tokenKey, userStr, time.Hour*12) return serializer.Suc(forms.UserLoginRes{ ID: u.ID, UserName: u.UserName, Nickname: u.Nickname, Status: u.Status, Avatar: u.Avatar, Token: base64.URLEncoding.EncodeToString([]byte(t)), }) } func (s *feishuService) GetFeiShuUserByCode(code string) (*larkauthen.GetUserInfoRespData, error) { // 使用获取到的 code 获取 token req := larkauthen.NewCreateAccessTokenReqBuilder().Body( larkauthen.NewCreateAccessTokenReqBodyBuilder(). GrantType("authorization_code"). Code(code). Build(), ).Build() resp, err := feishu.LarkClient.Authen.V1.AccessToken.Create(context.Background(), req) if err != nil { logrus.Warnf("GetAccessToken() failed with '%s'\n", err) return nil, err } if !resp.Success() { logrus.Warnf("logId: %s, error response: \n%s", resp.RequestId(), larkcore.Prettify(resp.CodeError)) return nil, err } userInfoResp, err := feishu.LarkClient.Authen.V1.UserInfo.Get(context.Background(), larkcore.WithUserAccessToken(*resp.Data.AccessToken)) // 处理错误 if err != nil { logrus.Warnf("GetUserInfo() failed with '%s'\n", err) return nil, err } // 服务端错误处理 if !userInfoResp.Success() { logrus.Warnf("logId: %s, error response: \n%s", userInfoResp.RequestId(), larkcore.Prettify(userInfoResp.CodeError)) return nil, errors.New(larkcore.Prettify(userInfoResp.CodeError)) } return userInfoResp.Data, nil } // 取出手机号码 func extractPhoneNumber(phone string) string { // 定义可能的国际前缀列表 prefixes := []string{"+86", "86"} for _, prefix := range prefixes { if strings.HasPrefix(phone, prefix) { // 如果手机号以该前缀开头,则返回去掉前缀后的部分 return strings.TrimPrefix(phone, prefix) } } // 如果没有匹配的前缀,直接返回原号码 return phone }