167 lines
5.3 KiB
Go
167 lines
5.3 KiB
Go
package controller
|
||
|
||
import (
|
||
"SciencesServer/app/api/admin/model"
|
||
model2 "SciencesServer/app/common/model"
|
||
"SciencesServer/app/handle"
|
||
"SciencesServer/app/service"
|
||
"SciencesServer/app/session"
|
||
"SciencesServer/config"
|
||
"SciencesServer/utils"
|
||
"errors"
|
||
"fmt"
|
||
)
|
||
|
||
type Account struct {
|
||
session *session.Admin
|
||
tenantID uint64
|
||
}
|
||
|
||
type AccountHandle func(session *session.Admin, tenantID uint64) *Account
|
||
|
||
type (
|
||
// loginHandleReturn 登陆操作返回信息
|
||
loginHandleReturn struct {
|
||
*model.SysUser
|
||
TenantID uint64 `json:"tenant_id"`
|
||
TenantIdentity model2.SysUserTenantIdentity
|
||
}
|
||
// AccountLoginParams 登陆参数
|
||
AccountLoginParams struct {
|
||
Account, Password, Captcha string
|
||
}
|
||
// AccountLoginResponse 登陆响应
|
||
AccountLoginResponse struct {
|
||
Token string `json:"token"`
|
||
EffectTime int `json:"effect_time"`
|
||
}
|
||
)
|
||
|
||
// loginHandle 登陆操作,1:账户密码登陆,2:短信验证登陆
|
||
var loginHandle = map[int]func(params *AccountLoginParams, tenantID uint64) (*loginHandleReturn, error){
|
||
1: loginForPassword, 2: loginForSmsCaptcha,
|
||
}
|
||
|
||
// loginForPassword 密码登陆
|
||
func loginForPassword(params *AccountLoginParams, tenantID uint64) (*loginHandleReturn, error) {
|
||
if params.Password == "" {
|
||
return nil, errors.New("操作错误,密码不可为空")
|
||
}
|
||
mSysUser := model.NewSysUser()
|
||
|
||
isExist, err := mSysUser.GetByAccountOrMobile(params.Account, tenantID)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
} else if !isExist {
|
||
return nil, errors.New("操作错误,当前帐号信息不存在或已被删除")
|
||
}
|
||
if !mSysUser.ValidatePassword(params.Password) {
|
||
return nil, errors.New("操作错误,用户名或密码错误")
|
||
}
|
||
out := &loginHandleReturn{SysUser: mSysUser, TenantIdentity: 0}
|
||
|
||
if !mSysUser.IsAdminUser() {
|
||
// 查询用户租户信息
|
||
mSysUserTenant := model.NewSysUserTenant()
|
||
|
||
if isExist, err = model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"},
|
||
model2.NewWhere("uid", mSysUser.UUID),
|
||
model2.NewWhere("tenant_id", tenantID)); err != nil {
|
||
return nil, err
|
||
} else if !isExist {
|
||
return nil, errors.New("操作错误,无权限登陆此后台,请联系管理员")
|
||
}
|
||
|
||
out.TenantID = tenantID
|
||
out.TenantIdentity = mSysUserTenant.Identity
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// loginForSmsCaptcha 短信验证码登陆
|
||
func loginForSmsCaptcha(params *AccountLoginParams, tenantID uint64) (*loginHandleReturn, error) {
|
||
if params.Captcha == "" {
|
||
return nil, errors.New("操作错误,验证码不可为空")
|
||
}
|
||
// 验证验证码
|
||
if pass, _ := handle.NewCaptcha().Validate(&handle.CaptchaSms{Mobile: params.Account, Captcha: params.Captcha}); !pass {
|
||
return nil, errors.New("操作错误,验证码错误")
|
||
}
|
||
mSysUser := model.NewSysUser()
|
||
|
||
isExist, err := model2.FirstField(mSysUser.SysUser, []string{
|
||
"id", "uuid", "name", "mobile", "is_admin", "status",
|
||
}, model2.NewWhere("mobile", params.Account))
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
} else if !isExist {
|
||
return nil, errors.New("操作错误,当前帐号信息不存在或已被删除")
|
||
}
|
||
out := &loginHandleReturn{SysUser: mSysUser, TenantIdentity: 0}
|
||
|
||
if !mSysUser.IsAdminUser() {
|
||
// 查询用户租户信息
|
||
mSysUserTenant := model.NewSysUserTenant()
|
||
|
||
if isExist, err = model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"},
|
||
model2.NewWhere("uid", mSysUser.UUID),
|
||
model2.NewWhere("tenant_id", tenantID)); err != nil {
|
||
return nil, err
|
||
} else if !isExist {
|
||
return nil, errors.New("操作错误,无权限登陆此后台,请联系管理员")
|
||
}
|
||
out.TenantID = tenantID
|
||
out.TenantIdentity = mSysUserTenant.Identity
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// Login 登录请求
|
||
func (c *Account) Login(mode int, params *AccountLoginParams, equipment, ip string) (*AccountLoginResponse, error) {
|
||
_handle, has := loginHandle[mode]
|
||
|
||
if !has {
|
||
return nil, errors.New("操作错误,未知的登陆模式")
|
||
}
|
||
data, err := _handle(params, c.tenantID)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
} else if data.Status != model2.SysUserStatusForNormal {
|
||
return nil, errors.New(fmt.Sprintf("操作错误,当前账号【%s】状态异常,已禁止登陆,请联系管理员", data.Name))
|
||
}
|
||
_session := session.NewAdmin()
|
||
_session.UID = data.UUID
|
||
_session.TenantID = data.TenantID
|
||
_session.Name = data.Name
|
||
_session.Mobile = data.Mobile
|
||
_session.IsAdmin = data.IsAdminUser()
|
||
_session.IsSystemAdmin = data.TenantIdentity == model2.SysUserTenantIdentityForSystemAdmin
|
||
|
||
_uid := data.UUIDString()
|
||
|
||
_session.Token = utils.JWTEncrypt(utils.StringToInt(config.SystemConfig[config.SysTokenEffectTime]),
|
||
map[string]interface{}{config.TokenForUID: _uid})
|
||
|
||
service.Publish(config.EventForRedisHashProduce, config.RedisKeyForAccountAdmin, _uid, _session)
|
||
service.Publish(config.EventForAccountLoginProduce, data.TenantID, data.ID, equipment, ip)
|
||
|
||
return &AccountLoginResponse{Token: _session.Token, EffectTime: utils.StringToInt(config.SystemConfig[config.SysTokenEffectTime])}, nil
|
||
}
|
||
|
||
// Logout 退出请求
|
||
func (c *Account) Logout() error {
|
||
if c.session != nil && c.session.UID > 0 {
|
||
service.Publish(config.EventForRedisHashDestroy, config.RedisKeyForAccountAdmin, utils.UintToString(c.session.UID))
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func NewAccount() AccountHandle {
|
||
return func(session *session.Admin, tenantID uint64) *Account {
|
||
return &Account{session: session, tenantID: tenantID}
|
||
}
|
||
}
|