mini_user_login_logic.go 4.3 KB
package user

import (
	"context"
	"fmt"
	"github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	miniConfig "github.com/silenceper/wechat/v2/miniprogram/config"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"

	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type MiniUserLoginLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewMiniUserLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniUserLoginLogic {
	return &MiniUserLoginLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *MiniUserLoginLogic) MiniUserLogin(req *types.MiniUserLoginRequest) (resp *types.MiniUserLoginResponse, err error) {
	var (
		loginInfo    *domain.LoginInfo
		token        string
		loginCreator domain.LoginCreator = WxClientLogin{l: l}
	)
	switch req.LoginType {
	case domain.LoginTypeWechatLogin:
		loginInfo, err = loginCreator.WechatLogin(domain.WechatLoginRequest{Code: req.WechatAuthCode, EncryptedData: req.WechatEncryptedData, IV: req.WechatIV})
	case domain.LoginTypeWechatPhoneLogin:
		loginInfo, err = loginCreator.WechatPhoneLogin(domain.WechatLoginRequest{Code: req.WechatAuthCode, EncryptedData: req.WechatEncryptedData, IV: req.WechatIV})
	case domain.LoginTypePhoneSmsCodeLogin:
		loginInfo, err = loginCreator.PhoneSmsCodeLogin(req.Phone, req.SmsCode)
	case domain.LoginTypePhonePasswordLogin:
		loginInfo, err = loginCreator.PhonePasswordLogin(req.Phone, req.Password)
	}
	if err != nil {
		return
	}
	if loginInfo.User == nil {
		return nil, xerr.NewErrMsgErr("用户不存在", err)
	}
	var userJwtToken = tool.UserToken{}
	if loginInfo.User != nil {
		userJwtToken.UserId = loginInfo.User.Id
		userJwtToken.CompanyId = loginInfo.User.CompanyId
		userJwtToken.ClientType = "mini"
	}
	token, err = userJwtToken.GenerateToken(l.svcCtx.Config.MiniAuth.AccessSecret, l.svcCtx.Config.MiniAuth.AccessExpire)
	if err != nil {
		return nil, xerr.NewErrMsgErr("登录失败", err)
	}
	resp = &types.MiniUserLoginResponse{
		Token:   token,
		Phone:   loginInfo.Phone,
		Success: true,
	}
	if loginInfo.User == nil {
		resp.Success = false
	}
	return
}

type WxClientLogin struct {
	l *MiniUserLoginLogic
}

func (c WxClientLogin) WechatPhoneLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) {
	code := r.Code
	miniprogram := wechat.NewWechat().GetMiniProgram(&miniConfig.Config{
		AppID:     c.l.svcCtx.Config.Wechat.AppID,
		AppSecret: c.l.svcCtx.Config.Wechat.AppSecret,
		Cache:     cache.NewMemory(),
	})
	authResult, err := miniprogram.GetAuth().GetPhoneNumber(code)
	if err != nil || authResult.ErrCode != 0 || authResult.PhoneInfo.PhoneNumber == "" {
		return nil, xerr.NewCodeErrMsg(xerr.ErrWxMiniAuthFailError, nil, fmt.Sprintf("发起授权请求失败1 err : %v , code : %s  , authResult : %+v", err, code, authResult))
	}
	var (
		users []*domain.User
		phone = authResult.PhoneInfo.PhoneNumber
	)
	conn := c.l.svcCtx.DefaultDBConn()
	_, users, err = c.l.svcCtx.UserRepository.Find(c.l.ctx, conn, domain.NewQueryOptions().
		MustWithKV("phone", phone).
		MustWithKV("auditStatus", []int{domain.UserAuditStatusPassed}))
	if err != nil {
		return nil, err
	}
	response := &domain.LoginInfo{
		Phone: phone,
	}
	if len(users) != 0 {
		response.User = users[0]
	}
	return response, nil
}

func (c WxClientLogin) WechatLogin(r domain.WechatLoginRequest) (*domain.LoginInfo, error) {
	return nil, nil
}

func (c WxClientLogin) PhonePasswordLogin(phone string, password string) (*domain.LoginInfo, error) {
	panic("implement me")
}

func (c WxClientLogin) PhoneSmsCodeLogin(phone string, code string) (*domain.LoginInfo, error) {
	var (
		users []*domain.User
		err   error
	)
	conn := c.l.svcCtx.DefaultDBConn()
	_, users, err = c.l.svcCtx.UserRepository.Find(c.l.ctx, conn, domain.NewQueryOptions().
		MustWithKV("phone", phone).
		MustWithKV("auditStatus", []int{domain.UserAuditStatusPassed}).
		WithFindOnly())
	if err != nil {
		return nil, err
	}
	response := &domain.LoginInfo{
		Phone: phone,
	}
	if len(users) != 0 {
		response.User = users[0]
	}
	return response, nil
}