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 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) } // 验证用户角色状态 rdb := query.Use(config.AdminDB).AdminRole result, err := rdb.Where(rdb.ID.Eq(int64(u.RoleID))).First() if err != nil { logrus.Warnf("AdminRole... err:%+v", err) return serializer.ParamErr("获取角色信息失败", err) } if result == nil { return serializer.ParamErr("获取角色信息失败", nil) } if result.Status != 1 { return serializer.ParamErr("角色权限已被禁用", nil) } // 生成token 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 }