451 lines
13 KiB
Go
451 lines
13 KiB
Go
package tenant
|
||
|
||
import (
|
||
"SciencesServer/app/api/controller"
|
||
auth2 "SciencesServer/app/api/controller/auth"
|
||
menu2 "SciencesServer/app/api/controller/menu"
|
||
"SciencesServer/app/api/model"
|
||
model2 "SciencesServer/app/common/model"
|
||
"SciencesServer/app/service"
|
||
"SciencesServer/config"
|
||
"SciencesServer/serve/orm"
|
||
"SciencesServer/utils"
|
||
"errors"
|
||
"fmt"
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
type Instance struct{ *controller.Platform }
|
||
|
||
type InstanceHandle func(session *service.Session) *Instance
|
||
|
||
type (
|
||
// InstanceInfo 租户信息
|
||
InstanceInfo struct {
|
||
*model.SysTenantInfo
|
||
Config *model2.SysTenantConfig `json:"config"`
|
||
}
|
||
// InstanceParams 租户参数信息
|
||
InstanceParams struct {
|
||
ID uint64
|
||
Image, Name, Account, Password, RepeatPwd string
|
||
Deadline, Remark string
|
||
}
|
||
// InstanceBasicInfo 租户基本信息
|
||
InstanceBasicInfo struct {
|
||
ID uint64 `json:"id"`
|
||
Name string `json:"name"`
|
||
}
|
||
// InstanceDetailType 租户信息类型
|
||
InstanceDetailType int
|
||
)
|
||
|
||
const (
|
||
// InstanceDetailTypeForBasic 基本信息
|
||
InstanceDetailTypeForBasic InstanceDetailType = iota + 1
|
||
// InstanceDetailTypeForMember 成员信息
|
||
InstanceDetailTypeForMember
|
||
// InstanceDetailTypeForAuth 权限信息
|
||
InstanceDetailTypeForAuth
|
||
)
|
||
|
||
// instanceDetailGetHandle 详细信息获取操作
|
||
var instanceDetailGetHandle = map[InstanceDetailType]func(id uint64) func(args ...interface{}) (interface{}, error){
|
||
InstanceDetailTypeForBasic: basic,
|
||
InstanceDetailTypeForMember: member,
|
||
InstanceDetailTypeForAuth: auth,
|
||
}
|
||
|
||
// basic 基本信息
|
||
func basic(id uint64) func(args ...interface{}) (interface{}, error) {
|
||
return func(args ...interface{}) (interface{}, error) {
|
||
mSysTenant := model.NewSysTenant()
|
||
mSysTenant.ID = id
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
} else if !isExist {
|
||
return nil, errors.New("信息不存在")
|
||
}
|
||
return &InstanceInfo{SysTenantInfo: &model.SysTenantInfo{
|
||
SysTenant: mSysTenant.SysTenant,
|
||
}, Config: mSysTenant.ConfigInfo()}, nil
|
||
}
|
||
}
|
||
|
||
// member 人员信息
|
||
func member(id uint64) func(args ...interface{}) (interface{}, error) {
|
||
return func(args ...interface{}) (interface{}, error) {
|
||
mSysUserTenant := model.NewSysUserTenant()
|
||
|
||
page := args[0].(int)
|
||
pageSize := args[1].(int)
|
||
|
||
where := []*model2.ModelWhere{model2.NewWhere("u_t.tenant_id", id)}
|
||
|
||
if args[2] != nil && args[2] != "" {
|
||
where = append(where, model2.NewWhereLike("u.name", args[2]))
|
||
}
|
||
if args[3] != nil && args[3].(int) > 0 {
|
||
where = append(where, model2.NewWhere("u_t.status", args[3]))
|
||
}
|
||
var count int64
|
||
|
||
out, err := mSysUserTenant.Member(page, pageSize, &count, where...)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &controller.ReturnPages{Data: out, Page: page, TotalCount: count}, nil
|
||
}
|
||
}
|
||
|
||
// auth 权限信息
|
||
func auth(id uint64) func(args ...interface{}) (interface{}, error) {
|
||
return func(args ...interface{}) (interface{}, error) {
|
||
mSysMenu := model.NewSysMenu()
|
||
|
||
_menu, err := mSysMenu.TenantMenu(id)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
mSysAuth := model.NewSysAuth()
|
||
|
||
_auth := make([]*model.SysAuthScene, 0)
|
||
|
||
if _auth, err = mSysAuth.TenantAuth(id); err != nil {
|
||
return nil, err
|
||
}
|
||
return map[string]interface{}{
|
||
"menu": menu2.TreeCheckedFunc(_menu, 0), "auth": auth2.TreeCheckedFunc(_auth, 0),
|
||
}, nil
|
||
}
|
||
}
|
||
|
||
// validateForCustomerCount 验证最大客户数
|
||
func (c *Instance) validateForCustomerCount(tenantID uint64, sysValue, srcValue int) (bool, error) {
|
||
if srcValue > sysValue {
|
||
return true, nil
|
||
}
|
||
mSysTenant := model.NewSysTenant()
|
||
|
||
var count int64
|
||
|
||
if err := model2.Count(mSysTenant.SysTenant, &count, model2.NewWhere("parent_id", tenantID)); err != nil {
|
||
return false, err
|
||
}
|
||
return int(count) <= srcValue, nil
|
||
}
|
||
|
||
// List 列表信息
|
||
func (c *Instance) List(name string, status, page, pageSize int) (*controller.ReturnPages, error) {
|
||
mSysTenant := model.NewSysTenant()
|
||
|
||
var count int64
|
||
|
||
where := []*model2.ModelWhere{model2.NewWhere("t.parent_id", 0)}
|
||
|
||
if name != "" {
|
||
where = append(where, model2.NewWhereLike("t.name", name))
|
||
}
|
||
if status > 0 {
|
||
where = append(where, model2.NewWhere("t.status", status))
|
||
}
|
||
out, err := mSysTenant.Tenants(page, pageSize, &count, where...)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
list := make([]*InstanceInfo, 0)
|
||
|
||
for _, v := range out {
|
||
v.Image.Image = v.Image.Analysis(config.SettingInfo.Domain)
|
||
|
||
list = append(list, &InstanceInfo{SysTenantInfo: v, Config: v.ConfigInfo()})
|
||
}
|
||
return &controller.ReturnPages{Data: list, Page: page, TotalCount: count}, nil
|
||
}
|
||
|
||
// Add 数据处理
|
||
func (c *Instance) Add(params *InstanceParams) error {
|
||
mSysTenant := model.NewSysTenant()
|
||
|
||
if params.Password != params.RepeatPwd {
|
||
return errors.New("密码不一致")
|
||
}
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant, model2.NewWhere("name", params.Name))
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if isExist {
|
||
return errors.New("该租户/公司名称已存在")
|
||
}
|
||
mSysUser := model.NewSysUser()
|
||
|
||
if isExist, err = model2.FirstWhere(mSysUser.SysUser, model2.NewWhere("account", params.Account)); err != nil {
|
||
return err
|
||
} else if isExist {
|
||
return errors.New("登录用户名已存在")
|
||
}
|
||
if err = orm.GetDB().Transaction(func(tx *gorm.DB) error {
|
||
mSysTenant.Image.Image = params.Image
|
||
mSysTenant.Name = params.Name
|
||
mSysTenant.Config = utils.AnyToJSON(&model2.SysTenantConfig{MaxDevices: 0, MaxCustomer: 0, Protocol: 0})
|
||
mSysTenant.Deadline = utils.DateTimeToTime(params.Deadline + " 23:59:59")
|
||
mSysTenant.Remark = params.Remark
|
||
|
||
if err = model2.Create(mSysTenant.SysTenant, tx); err != nil {
|
||
return err
|
||
}
|
||
mSysUser.Name = mSysTenant.Name
|
||
mSysUser.Account = params.Account
|
||
mSysUser.Password = params.Password
|
||
|
||
if err = model2.Create(mSysUser.SysUser, tx); err != nil {
|
||
return err
|
||
}
|
||
mSysUserTenant := model.NewSysUserTenant()
|
||
mSysUserTenant.TenantID = mSysTenant.ID
|
||
mSysUserTenant.UID = mSysUser.UUID
|
||
mSysUserTenant.Identity = model2.SysUserTenantIdentityForSystemAdmin
|
||
|
||
if err = model2.Create(mSysUserTenant.SysUserTenant, tx); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
service.Publish(config.EventForRedisListProduce, config.RedisKeyForTenant, mSysTenant.Key)
|
||
|
||
return nil
|
||
}
|
||
|
||
// Edit 修改信息
|
||
func (c *Instance) Edit(params *InstanceParams) error {
|
||
mSysTenant := model.NewSysTenant()
|
||
mSysTenant.ID = params.ID
|
||
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("租户/公司信息不存在")
|
||
} else if c.TenantID > 0 {
|
||
if mSysTenant.ParentID <= 0 {
|
||
return errors.New("不可修改其他租户/公司的信息")
|
||
} else if c.TenantID != mSysTenant.ParentID {
|
||
return errors.New("不可修改其他租户/公司的客户信息")
|
||
}
|
||
}
|
||
if mSysTenant.Name != params.Name {
|
||
if isExist, err = model2.FirstWhere(mSysTenant.SysTenant, model2.NewWhere("name", params.Name)); err != nil {
|
||
return err
|
||
} else if isExist {
|
||
return errors.New("该租户/公司名称已存在")
|
||
}
|
||
}
|
||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{
|
||
"name": params.Name, "image": params.Image, "remark": params.Remark, "updated_at": time.Now(),
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// EditPassword 修改信息
|
||
func (c *Instance) EditPassword(params *InstanceParams) error {
|
||
mSysTenant := model.NewSysTenant()
|
||
mSysTenant.ID = params.ID
|
||
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("租户/公司信息不存在")
|
||
} else if c.TenantID > 0 {
|
||
if mSysTenant.ParentID <= 0 {
|
||
return errors.New("不可修改其他租户/公司的用户密码信息")
|
||
} else if c.TenantID != mSysTenant.ParentID {
|
||
return errors.New("不可修改其他租户/公司的用户密码信息")
|
||
}
|
||
}
|
||
if params.Password != params.RepeatPwd {
|
||
return errors.New("密码不一致")
|
||
}
|
||
// 查询该租户下管理员信息
|
||
mSysUserTenant := model.NewSysUserTenant()
|
||
|
||
if isExist, err = model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "uid", "identity"},
|
||
model2.NewWhere("tenant_id", params.ID), model2.NewWhere("identity", model2.SysUserTenantIdentityForSystemAdmin)); err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("该租户/公司下管理员信息不存在或已被删除")
|
||
}
|
||
mSysUser := model.NewSysUser()
|
||
mSysUser.Password = params.Password
|
||
mSysUser.Pass()
|
||
|
||
if err = model2.UpdatesWhere(mSysUser.SysUser, map[string]interface{}{
|
||
"password": mSysUser.Password, "salt": mSysUser.Salt, "updated_at": time.Now(),
|
||
}, []*model2.ModelWhere{model2.NewWhere("uuid", mSysUserTenant.UID)}); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Detail 详细信息
|
||
func (c *Instance) Detail(id uint64, tType InstanceDetailType, page, pageSize int, name string, status int) (interface{}, error) {
|
||
handle, has := instanceDetailGetHandle[tType]
|
||
|
||
if !has {
|
||
return nil, errors.New(fmt.Sprintf("Unknown Tenant Detail Type:%d", tType))
|
||
}
|
||
out, err := handle(id)(page, pageSize, name, status)
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return out, nil
|
||
}
|
||
|
||
// Renewal 续期操作
|
||
func (c *Instance) Renewal(id uint64, deadline string) error {
|
||
mSysTenant := model.NewSysTenant()
|
||
mSysTenant.ID = id
|
||
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("租户/公司信息不存在")
|
||
} else if c.TenantID > 0 {
|
||
if mSysTenant.ParentID <= 0 {
|
||
return errors.New("非超级管理员,不可操作")
|
||
} else if c.TenantID != mSysTenant.ParentID {
|
||
return errors.New("非法操作,不可续期他人客户使用期限")
|
||
}
|
||
}
|
||
now := time.Now()
|
||
|
||
updates := make(map[string]interface{}, 0)
|
||
updates["updated_at"] = now
|
||
|
||
_deadline := utils.DateTimeToTime(deadline + " 23:59:59")
|
||
|
||
if _deadline.Before(mSysTenant.Deadline) {
|
||
return errors.New("续期时间异常")
|
||
}
|
||
updates["deadline"] = _deadline
|
||
|
||
if mSysTenant.Status != model2.SysTenantStatusForNormal && _deadline.After(now) {
|
||
updates["status"] = model2.SysTenantStatusForNormal
|
||
}
|
||
if err = model2.Updates(mSysTenant.SysTenant, updates); err != nil {
|
||
return err
|
||
}
|
||
service.Publish(config.EventForRedisListProduce, config.RedisKeyForTenant, mSysTenant.Key)
|
||
return nil
|
||
}
|
||
|
||
// StartUp 启用处理
|
||
func (c *Instance) StartUp(id uint64) error {
|
||
mSysTenant := model.NewSysTenant()
|
||
mSysTenant.ID = id
|
||
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("租户/公司/客户信息不存在")
|
||
} else if c.TenantID > 0 {
|
||
if mSysTenant.ParentID <= 0 {
|
||
return errors.New("非超级管理员,不可操作")
|
||
} else if c.TenantID != mSysTenant.ParentID {
|
||
return errors.New("不可启用其他租户/公司客户")
|
||
}
|
||
} else if mSysTenant.Status == model2.SysTenantStatusForNormal {
|
||
return errors.New("该租户/公司/客户已是启用状态")
|
||
}
|
||
status := model2.SysTenantStatusForNormal
|
||
|
||
now := time.Now()
|
||
|
||
if mSysTenant.Deadline.Before(now) {
|
||
status = model2.SysTenantStatusForExpired
|
||
}
|
||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{
|
||
"status": status, "updated_at": now,
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// Disable 禁用处理
|
||
func (c *Instance) Disable(id uint64) error {
|
||
mSysTenant := model.NewSysTenant()
|
||
mSysTenant.ID = id
|
||
|
||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("租户/公司/客户信息不存在")
|
||
} else if c.TenantID > 0 {
|
||
if mSysTenant.ParentID <= 0 {
|
||
return errors.New("非超级管理员,不可操作")
|
||
} else if c.TenantID != mSysTenant.ParentID {
|
||
return errors.New("不可启用其他租户/公司/客户")
|
||
}
|
||
} else if mSysTenant.Status == model2.SysTenantStatusForDisable {
|
||
return errors.New("该租户/公司/客户已是禁用状态")
|
||
}
|
||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{
|
||
"status": model2.SysTenantStatusForDisable, "updated_at": time.Now(),
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
// TODO:推送用户强制退出,并强行删除所有产品数据
|
||
service.Publish(config.EventForRedisListDestroy, config.RedisKeyForTenant, mSysTenant.Key)
|
||
return nil
|
||
}
|
||
|
||
// MemberBind 人员绑定/解绑
|
||
func (c *Instance) MemberBind(id uint64, status int) error {
|
||
mSysUserTenant := model.NewSysUserTenant()
|
||
mSysUserTenant.ID = id
|
||
|
||
isExist, err := model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"})
|
||
|
||
if err != nil {
|
||
return err
|
||
} else if !isExist {
|
||
return errors.New("用户信息不存在")
|
||
}
|
||
if model2.SysUserTenantStatus(status) == mSysUserTenant.Status {
|
||
return errors.New("状态异常,不可操作")
|
||
}
|
||
if err := model2.Updates(mSysUserTenant.SysUserTenant, map[string]interface{}{
|
||
"status": status, "updated_at": time.Now(),
|
||
}); err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func NewInstance() InstanceHandle {
|
||
return func(session *service.Session) *Instance {
|
||
return &Instance{Platform: &controller.Platform{Session: session}}
|
||
}
|
||
}
|