feat:完善信息

This commit is contained in:
henry
2021-09-29 16:25:56 +08:00
parent b876eab301
commit c556053feb
16 changed files with 382 additions and 84 deletions

View File

@ -3,6 +3,7 @@ package api
import (
"SciencesServer/app/common/api"
"SciencesServer/app/enterprise/controller/account"
"SciencesServer/app/service"
"github.com/gin-gonic/gin"
)
@ -10,10 +11,17 @@ type Account struct{}
type (
accountLoginForm struct {
Mode int `json:"mode" form:"mode" binding:"required"`
Mode int `json:"mode" form:"mode" binding:"required"`
Mobile string `json:"mobile" form:"mobile"`
Captcha string `json:"captcha" form:"captcha"`
Password string `json:"password" form:"password"`
}
accountRegisterForm struct {
Name string `json:"name" form:"name" binding:"required"`
Mobile string `json:"mobile" form:"mobile" binding:"required"`
Captcha string `json:"captcha" form:"captcha" binding:"required"`
Password string `json:"password" form:"password" binding:"required"`
RepeatPass string `json:"repeat_pass" form:"repeat_pass" binding:"required"`
}
)
@ -24,22 +32,45 @@ func (a *Account) Login(c *gin.Context) {
api.APIFailure(err.(error))(c)
return
}
data, err := account.NewLogin().Login()(account.LoginMode(form.Mode), nil)
data, err := account.NewLogin()().Launch(account.LoginMode(form.Mode), &account.LoginRequest{
Captcha: struct {
Mobile string
Captcha string
}{Mobile: form.Mobile, Captcha: form.Captcha},
Password: struct {
Mobile string
Password string
}{Mobile: form.Mobile, Password: form.Password},
})
api.APIResponse(err, data)
}
func (a *Account) Register() {
func (a *Account) Register(c *gin.Context) {
form := new(accountRegisterForm)
if err := api.Bind(form)(c); err != nil {
api.APIFailure(err.(error))(c)
return
}
data, err := account.NewRegister()().Launch(&account.RegisterRequest{
Name: form.Name, Mobile: form.Mobile, Captcha: form.Captcha,
Password: form.Password, RepeatPass: form.RepeatPass,
})
api.APIResponse(err, data)
}
func (c *Account) BindName() {
func (a *Account) BindMobile() {
account.NewOther()().BindMobile()
}
func (c *Account) BindMobile() {
}
func (a *Account) Logout() {
func (a *Account) Logout(c *gin.Context) {
handle := api.GetSession()(c)
session := new(service.SessionEnterprise)
if handle != nil {
session = handle.(*service.SessionEnterprise)
}
err := account.NewLogout()(session).Launch()
api.APIResponse(err)(c)
}

View File

@ -0,0 +1,14 @@
package api
import (
"SciencesServer/app/common/api"
"SciencesServer/app/enterprise/controller"
"github.com/gin-gonic/gin"
)
type Config struct{}
func (a *Config) Identity(c *gin.Context) {
data := controller.NewConfig().Identity()
api.APISuccess(data)
}

View File

@ -0,0 +1,3 @@
package api
type User struct{}

View File

@ -0,0 +1,41 @@
package account
import (
"SciencesServer/app/enterprise/model"
"SciencesServer/app/service"
"SciencesServer/config"
"SciencesServer/utils"
)
type Account struct{}
type LoginCallback func(user *model.TenantUser) *LoginResponse
type (
LoginResponse struct {
Token string `json:"token"`
EffectTime int `json:"effect_time"`
}
)
func (c *Account) Login() LoginCallback {
return func(mTenantUser *model.TenantUser) *LoginResponse {
token := utils.JWTEncrypt(config.SettingInfo.TokenEffectTime, map[string]interface{}{
config.TokenForUID: mTenantUser.UUID,
})
session := service.NewSessionEnterprise()
session.Token = token
session.UID = mTenantUser.UUID
session.Name = mTenantUser.Name
session.Mobile = mTenantUser.Mobile
session.Identity = mTenantUser.Identity
service.Publish(config.EventForRedisHashProduce, config.RedisKeyForAccount, mTenantUser.UUIDToString(), session)
return &LoginResponse{Token: token, EffectTime: config.SettingInfo.TokenEffectTime}
}
}
func NewAccount() *Account {
return &Account{}
}

View File

@ -4,7 +4,6 @@ import (
model2 "SciencesServer/app/common/model"
"SciencesServer/app/enterprise/model"
"SciencesServer/app/handle"
"SciencesServer/config"
"SciencesServer/utils"
"errors"
)
@ -12,48 +11,46 @@ import (
type Login struct{}
type (
LoginHandle func(LoginMode, *LoginRequest) (*LoginResponse, error)
LoginHandle func() *Login
)
type (
LoginRequest struct {
Captcha struct {
Mobile string `json:"mobile"`
Captcha string `json:"captcha"`
Mobile string
Captcha string
}
Password struct {
Mobile string `json:"mobile"`
Password string `json:"password"`
Mobile string
Password string
}
Platform struct {
OpenID string `json:"open_id"`
OpenID string
}
}
LoginResponse struct {
Token string `json:"token"`
EffectTime int `json:"effect_time"`
}
)
// LoginMode 登陆模式
type LoginMode int
const (
LoginModeForCaptcha LoginMode = iota + 1e2 + 1 // 验证码登陆
LoginModeForPassword // 密码登陆
LoginModeForWechat // 微信登陆
LoginModeForQQ // QQ登陆
LoginModeForSmsCaptcha LoginMode = iota + 1e2 + 1 // 短信验证码登陆
LoginModeForPassword // 密码登陆
LoginModeForWechat // 微信登陆
LoginModeForQQ // QQ登陆
)
var loginHandle = map[LoginMode]func(*LoginRequest) (*model.TenantUser, error){
LoginModeForCaptcha: loginForCaptcha, LoginModeForPassword: loginForPassword,
LoginModeForSmsCaptcha: loginForSmsCaptcha, LoginModeForPassword: loginForPassword,
}
// loginForCaptcha 验证码登陆
func loginForCaptcha(req *LoginRequest) (*model.TenantUser, error) {
// loginForSmsCaptcha 短信验证码登陆
func loginForSmsCaptcha(req *LoginRequest) (*model.TenantUser, error) {
if !utils.ValidateMobile(req.Captcha.Mobile) {
return nil, errors.New("手机号码格式异常")
}
pass, err := handle.NewCaptcha().Validate(&handle.CaptchaSms{
Mobile: req.Captcha.Mobile,
Captcha: req.Captcha.Captcha,
Mobile: req.Captcha.Mobile, Captcha: req.Captcha.Captcha,
})
if err != nil {
return nil, err
@ -64,20 +61,26 @@ func loginForCaptcha(req *LoginRequest) (*model.TenantUser, error) {
mTenantUsr := model.NewTenantUser()
if isExist, err = model2.FirstField(mTenantUsr.TenantUser, []string{"id", "name", "status"},
if isExist, err = model2.FirstField(mTenantUsr.TenantUser, []string{"id", "uuid", "name", "mobile", "status"},
model2.NewWhere("mobile", req.Captcha.Mobile)); err != nil {
return nil, err
} else if isExist {
return nil, errors.New("当前手机号码未注册")
return mTenantUsr, nil
}
mTenantUsr.Name = req.Captcha.Mobile
mTenantUsr.Password = utils.GetRandomString(12)
return mTenantUsr, nil
}
// loginForPassword 密码登陆
func loginForPassword(req *LoginRequest) (*model.TenantUser, error) {
if !utils.ValidateMobile(req.Password.Mobile) {
return nil, errors.New("手机号码格式异常")
}
mTenantUsr := model.NewTenantUser()
isExist, err := model2.FirstField(mTenantUsr.TenantUser, []string{"id", "name", "status"},
isExist, err := model2.FirstField(mTenantUsr.TenantUser, []string{"id", "uuid", "name", "mobile",
"password", "salt", "status"},
model2.NewWhere("mobile", req.Password.Mobile))
if err != nil {
@ -95,27 +98,46 @@ func loginForPlatform(req *LoginRequest) error {
return nil
}
func (c *Login) Login() LoginHandle {
return func(mode LoginMode, req *LoginRequest) (*LoginResponse, error) {
handle, has := loginHandle[mode]
func (c *Login) Launch(mode LoginMode, req *LoginRequest) (*LoginResponse, error) {
handle, has := loginHandle[mode]
if !has {
return nil, errors.New("未知的登陆模式")
}
user, err := handle(req)
if !has {
return nil, errors.New("未知的登陆模式")
}
user, err := handle(req)
if err != nil {
return nil, err
}
token := utils.JWTEncrypt(config.SettingInfo.TokenEffectTime, map[string]interface{}{
config.TokenForUID: user.UUID,
})
return &LoginResponse{
Token: token, EffectTime: config.SettingInfo.TokenEffectTime,
}, nil
if err != nil {
return nil, err
}
if user.Status != model2.AccountStatusForEnable {
return nil, errors.New("该账号已禁止登陆,请联系管理员")
}
return NewAccount().Login()(user), err
}
func (c *Login) BindName(token, name string) {
// 解析token
tokenInfo := utils.JWTDecrypt(token)
if tokenInfo == nil {
//return errors.New("")
}
}
func NewLogin() *Login {
return &Login{}
func (c *Login) BindMobile(token, mobile, captcha string) (*LoginResponse, error) {
pass, err := handle.NewCaptcha().Validate(&handle.CaptchaSms{
Mobile: mobile, Captcha: captcha,
})
if err != nil {
return nil, err
} else if !pass {
return nil, errors.New("验证码错误或已过期")
}
return nil, err
}
func NewLogin() LoginHandle {
return func() *Login {
return &Login{}
}
}

View File

@ -0,0 +1,22 @@
package account
import (
"SciencesServer/app/service"
"SciencesServer/config"
"SciencesServer/utils"
)
type Logout struct{ *service.SessionEnterprise }
type LogoutHandle func(*service.SessionEnterprise) *Logout
func (c *Logout) Launch() error {
service.Publish(config.EventForRedisHashDestroy, config.RedisKeyForAccount, utils.UintToString(c.UID))
return nil
}
func NewLogout() LogoutHandle {
return func(enterprise *service.SessionEnterprise) *Logout {
return &Logout{enterprise}
}
}

View File

@ -0,0 +1,15 @@
package account
type Other struct{}
type OtherHandle func() *Other
func (c *Other) BindMobile() {
}
func NewOther() OtherHandle {
return func() *Other {
return &Other{}
}
}

View File

@ -0,0 +1,68 @@
package account
import (
model2 "SciencesServer/app/common/model"
"SciencesServer/app/enterprise/model"
"SciencesServer/app/handle"
"errors"
)
type Register struct{}
type RegisterHandle func() *Register
type (
RegisterRequest struct {
Name, Mobile, Captcha, Password, RepeatPass string
}
)
func (c *RegisterRequest) checkPassword() bool {
return c.Password == c.RepeatPass
}
func (c *RegisterRequest) checkUserExist(mTenantUser *model.TenantUser) (bool, error) {
var count int64
if err := model2.Count(mTenantUser.TenantUser, &count, model2.NewWhere("mobile", c.Mobile)); err != nil {
return false, err
}
return count > 0, nil
}
func (c *RegisterRequest) checkCaptcha() (bool, error) {
return handle.NewCaptcha().Validate(&handle.CaptchaSms{Captcha: c.Captcha, Mobile: c.Mobile})
}
func (c *Register) Launch(req *RegisterRequest) (*LoginResponse, error) {
if req.checkPassword() {
return nil, errors.New("两次密码不一致")
}
mTenantUser := model.NewTenantUser()
pass, err := req.checkUserExist(mTenantUser)
if err != nil {
return nil, err
} else if pass {
return nil, errors.New("当前手机号码已注册")
}
if pass, err = req.checkCaptcha(); err != nil {
return nil, err
} else if !pass {
return nil, errors.New("验证码错误或已过期")
}
mTenantUser.Name = req.Name
mTenantUser.Mobile = req.Mobile
mTenantUser.Password = req.Password
if err = model2.Create(mTenantUser.TenantUser); err != nil {
return nil, err
}
return NewAccount().Login()(mTenantUser), err
}
func NewRegister() RegisterHandle {
return func() *Register {
return &Register{}
}
}

View File

@ -0,0 +1,13 @@
package controller
import "SciencesServer/config"
type Config struct{}
func (c *Config) Identity() map[uint]string {
return config.TenantUserIdentityData
}
func NewConfig() *Config {
return &Config{}
}

View File

@ -1,17 +1,20 @@
package model
import "SciencesServer/app/common/model"
import (
"SciencesServer/app/common/model"
"SciencesServer/utils"
)
type TenantUser struct {
*model.TenantUser
}
func (m *TenantUser) UUIDToString() string {
return ""
return utils.UintToString(m.UUID)
}
func (m *TenantUser) ValidatePassword(password string) bool {
return true
return utils.HashCompare([]byte(m.Password), []byte(utils.Md5String(password, m.Salt)))
}
func NewTenantUser() *TenantUser {