package service import ( "context" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "golang.org/x/crypto/bcrypt" "observer-server/biz/dao" "observer-server/biz/model/dto" "observer-server/common" ) // authService 账号业务:注册(license 表即账号表,注册即插行)、登录(bcrypt 校验 + 签发 token) type authService struct{} var Auth = &authService{} // Register 注册:已注册(有密码)报错;存在运营手动授权先建的占位行(无密码)时补写密码完成注册。 func (s *authService) Register(ctx context.Context, req *dto.RegisterReq) (*dto.RegisterRes, error) { hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) if err != nil { return nil, gerror.Wrap(err, "密码加密失败") } err = common.Serial().Submit(ctx, func() error { return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { lic, err := dao.License.GetByPhoneInTx(ctx, tx, req.Phone) if err != nil { return err } if lic == nil { return dao.License.Register(ctx, tx, req.Phone, string(hash)) } if lic.Password == "" { return dao.License.SetPasswordInTx(ctx, tx, req.Phone, string(hash)) } return gerror.New("该手机号已注册") }) }) if err != nil { return nil, err } common.ClearCache(ctx, "license:"+req.Phone) return &dto.RegisterRes{}, nil } // Login 登录:绕缓存查账号(密码变更即时生效)→ bcrypt 比对 → 签发 token func (s *authService) Login(ctx context.Context, req *dto.LoginReq) (*dto.LoginRes, error) { lic, err := dao.License.GetByPhoneNoCache(ctx, req.Phone) if err != nil { return nil, err } if lic == nil || lic.Password == "" { return nil, gerror.New("账号或密码错误") } if err := bcrypt.CompareHashAndPassword([]byte(lic.Password), []byte(req.Password)); err != nil { return nil, gerror.New("账号或密码错误") } token, err := common.SignToken(ctx, req.Phone) if err != nil { return nil, err } return &dto.LoginRes{Token: token}, nil }