package analysisdevicelogic import ( "context" "lone-services/pkg/utils" "lone-services/pkg/validate" analysis "lone-services/rpc/analysis/pb" userpb "lone-services/rpc/user/pb" "lone-services/services/analysis/internal/dao" "lone-services/services/analysis/internal/face" "lone-services/services/analysis/internal/logic/common" "lone-services/services/analysis/internal/svc" "lone-services/services/analysis/validator" jsoniter "github.com/json-iterator/go" "github.com/zeromicro/go-zero/core/logx" ) type FaceLoginLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewFaceLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FaceLoginLogic { return &FaceLoginLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } type faceLoginResult struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` Info jsoniter.RawMessage `json:"info"` Status int `json:"status"` } func (l *FaceLoginLogic) FaceLogin(in *analysis.FaceLoginReq) (*analysis.Response, error) { var req validator.FaceLoginValidator if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { return common.OutResponse(utils.ErrorParams, msg), nil } if len(req.File) == utils.NumberZero { return common.FailResponse(utils.ErrorFileUpFailed), nil } imgPath, cleanup, err := face.PrepareImagePath(req.File, utils.StringEmpty) if err != nil { l.Errorf("face login prepare image: %v", err) return common.FailResponse(utils.ErrorFileUpFailed), nil } defer cleanup() vector, err := face.GetFaceVector(imgPath) if err != nil { l.Errorf("face login vector: %v", err) return common.FailResponse(utils.ErrorNotFace), nil } userID, score, err := face.SearchUser(vector) l.Infof("face login user_id=%d score=%v err=%v", userID, score, err) if err != nil { return common.FailResponse(utils.ErrorFaceNotMatch), nil } if l.svcCtx.UserSvcName == utils.StringEmpty { return common.FailResponse(utils.Fail), nil } cli, err := svc.GetRpcClient(l.svcCtx.UserSvcName) if err != nil { l.Errorf("face login user rpc: %v", err) return common.FailResponse(utils.Fail), nil } token, err := userpb.NewUserClient(cli.Conn()).InternalLoginByUserId(l.ctx, &userpb.InternalLoginByUserIdReq{ UserId: userID, ClientCode: dao.ClientCodeUserSkin, }) if err != nil { l.Errorf("face login issue token: %v", err) return common.FailResponse(utils.ErrorFaceNotMatch), nil } status := utils.NumberOne bizId := parseSessionBizId(token.GetInfo()) if bizId > utils.NumberZero { if row, loadErr := common.LoadAnalysisUser(bizId); loadErr == nil && row != nil { status = analysisUserStatus(*row) } } var info jsoniter.RawMessage if token.GetInfo() != utils.StringEmpty { info = jsoniter.RawMessage(token.GetInfo()) } else { info = jsoniter.RawMessage("{}") } return common.OkResponse(faceLoginResult{ AccessToken: token.GetAccessToken(), RefreshToken: token.GetRefreshToken(), Info: info, Status: status, }), nil } func parseSessionBizId(info string) int64 { if info == utils.StringEmpty { return utils.NumberZero } var sess struct { BizId int64 `json:"biz_id"` } if err := jsoniter.UnmarshalFromString(info, &sess); err != nil { return utils.NumberZero } return sess.BizId } func analysisUserStatus(row dao.User) int { status := utils.NumberOne if row.IsRegistered == uint8(utils.StatusOk) { status = utils.NumberTwo } if row.IsFaceVerified == uint8(utils.StatusOk) { status = utils.NumberThree } if row.IsProfileCompleted == uint8(utils.StatusOk) { status = utils.NumberFour } return status }