123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- 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"
- "strconv"
- "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, config.TokenExpireTime)
- config.TokenRedis.Set(tokenKey, userStr, config.TokenExpireTime)
- 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, config.TokenExpireTime)
- 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, config.TokenExpireTime)
- 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
- }
|