feat:完善项目信息
This commit is contained in:
@ -1,8 +1,11 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
tenant2 "SciencesServer/app/api/admin/controller/tenant"
|
||||
"SciencesServer/app/api/admin/controller/tenant"
|
||||
"SciencesServer/app/basic/api"
|
||||
"SciencesServer/app/basic/config"
|
||||
"SciencesServer/app/service"
|
||||
"SciencesServer/app/session"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -12,441 +15,98 @@ type Tenant struct{}
|
||||
type (
|
||||
// tenantForm 基本信息
|
||||
tenantForm struct {
|
||||
Name string `json:"name" form:"name" binding:"required"` // 名称
|
||||
imageForm // 图片
|
||||
Account string `json:"account" form:"account" binding:"required"` // 登录帐号
|
||||
Password string `json:"password" form:"password" binding:"required"` // 登录密码
|
||||
RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd" binding:"required"` // 重复登录密码
|
||||
Deadline string `json:"deadline" form:"deadline" binding:"required"` // 协约终止时间
|
||||
Remark string `json:"remark" form:"remark"` // 备注
|
||||
}
|
||||
// tenantSettingForm 配置信息
|
||||
tenantSettingForm struct {
|
||||
Protocol []uint `json:"protocol" form:"protocol" binding:"required"` // 消息协议
|
||||
MaxDevices int `json:"max_devices" form:"max_devices" binding:"required"` // 允许最多的设备数
|
||||
MaxCustomer int `json:"max_customer" form:"max_customer"` // 允许最多的客户数
|
||||
Name string `json:"name" form:"name" binding:"required"` // 名称
|
||||
Domain string `json:"domain" form:"domain" binding:"required"` // 域名
|
||||
Contact string `json:"contact" form:"contact" binding:"required"` // 联系人
|
||||
ContactMobile string `json:"contact_mobile" form:"contact_mobile" binding:"required"` // 联系方式
|
||||
Province string `json:"province" form:"province" binding:"required"` // 省
|
||||
City string `json:"city" form:"city" binding:"city"` // 市区
|
||||
Remark string `json:"remark" form:"remark"` // 备注
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* @apiDefine Tenant 租户管理
|
||||
*/
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/list 租户列表
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantList
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {String} [name='""'] 租户名称
|
||||
* @apiParam {Number} [status=0] 租户状态
|
||||
* @apiParam {Number} current 当前页
|
||||
* @apiParam {Number} page_size 页展示数
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
* @apiSuccess (200) {Array} data 具体信息
|
||||
* @apiSuccess (200) {Number} data.id ID
|
||||
* @apiSuccess (200) {String} data.key 标识key
|
||||
* @apiSuccess (200) {String} data.name 公司名称
|
||||
* @apiSuccess (200) {Time} data.deadline 协议到期时间
|
||||
* @apiSuccess (200) {Number} data.device_count 设备数量
|
||||
* @apiSuccess (200) {Json} data.config 配置信息
|
||||
* @apiSuccess (200) {Number} data.config.max_devices 最大设备数
|
||||
* @apiSuccess (200) {Number} data.config.max_customer 最大客户数
|
||||
* @apiSuccess (200) {Number} data.config.protocol 支持协议(&)
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": [
|
||||
* {
|
||||
* "id": 1,
|
||||
* "key": "3xPdWH",
|
||||
* "image": "",
|
||||
* "name": "商挈智能",
|
||||
* "deadline": "2021-12-31T23:59:59+08:00",
|
||||
* "remark": "测试",
|
||||
* "created_at": "2021-07-27T10:45:18+08:00",
|
||||
* "updated_at": "2021-07-27T10:45:18+08:00",
|
||||
* "device_count": 0,
|
||||
* "config": {
|
||||
* "max_devices": 1,
|
||||
* "max_customer": 1,
|
||||
* "protocol": 3
|
||||
* }
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) List(c *gin.Context) {
|
||||
func (a *Tenant) Instance(c *gin.Context) {
|
||||
form := &struct {
|
||||
Name string `json:"name" form:"name"`
|
||||
Status int `json:"status" form:"status"`
|
||||
pageForm
|
||||
Name string `json:"name" form:"name"`
|
||||
api.PageForm
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
if err := api.Bind(form)(c); err != nil {
|
||||
api.APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
data, err := tenant2.NewInstance()(getSession()(c).(*service.Session)).List(form.Name, form.Status, form.Page, form.PageSize)
|
||||
APIResponse(err, data)(c)
|
||||
data, err := tenant.NewInstance()(api.GetSession()(c).(*session.Admin)).Index(form.Name, form.Page, form.PageSize)
|
||||
api.APIResponse(err, data)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/add 租户添加
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantAdd
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {String} name 租户名称
|
||||
* @apiParam {String} image 租户图片
|
||||
* @apiParam {String} account 租户管理员登录帐号
|
||||
* @apiParam {String} password 租户管理员登录密码
|
||||
* @apiParam {String} repeat_pwd 重复密码
|
||||
* @apiParam {Number} max_devices 最大设备数
|
||||
* @apiParam {Number} [max_customer=0] 租户可拥有的最大客户数
|
||||
* @apiParam {Array.Number} protocol 消息协议
|
||||
* @apiParam {Time} deadline 协议有效期:2021-12-31
|
||||
* @apiParam {String} [remark="''"] 备注信息
|
||||
* @apiParam {Number} current 当前页
|
||||
* @apiParam {Number} page_size 页展示数
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) Add(c *gin.Context) {
|
||||
form := new(tenantForm)
|
||||
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
if err := api.Bind(form)(c); err != nil {
|
||||
api.APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).Add(&tenant2.InstanceParams{Name: form.Name,
|
||||
Image: form.FilterImageURL(), Account: form.Account, Password: form.Password, RepeatPwd: form.RepeatPwd,
|
||||
Deadline: form.Deadline, Remark: form.Remark,
|
||||
err := tenant.NewInstance()(api.GetSession()(c).(*session.Admin)).Form(&tenant.InstanceParams{Name: form.Name,
|
||||
Domain: form.Domain, Contact: form.Contact, ContactMobile: form.ContactMobile,
|
||||
Area: config.Area{Province: form.Province, City: form.City}, Remark: form.Remark,
|
||||
})
|
||||
APIResponse(err)(c)
|
||||
api.APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/edit 租户修改
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantEdit
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
* @apiParam {String} name 租户名称
|
||||
* @apiParam {String} image 租户图片
|
||||
* @apiParam {String} [remark="''"] 备注信息
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) Edit(c *gin.Context) {
|
||||
form := &struct {
|
||||
idForm
|
||||
Name string `json:"name" form:"name" binding:"required"`
|
||||
imageForm
|
||||
Remark string `json:"remark" form:"remark"`
|
||||
api.IDStringForm
|
||||
tenantForm
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
if err := api.Bind(form)(c); err != nil {
|
||||
api.APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).Edit(&tenant2.InstanceParams{ID: form.ID, Name: form.Name,
|
||||
Image: form.FilterImageURL(), Remark: form.Remark,
|
||||
err := tenant.NewInstance()(api.GetSession()(c).(*session.Admin)).Form(&tenant.InstanceParams{ID: form.Convert(),
|
||||
Name: form.Name, Domain: form.Domain, Contact: form.Contact, ContactMobile: form.ContactMobile,
|
||||
Area: config.Area{Province: form.Province, City: form.City}, Remark: form.Remark,
|
||||
})
|
||||
APIResponse(err)(c)
|
||||
api.APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/edit/password 租户修改密码
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantEditPassword
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
* @apiParam {String} name 租户名称
|
||||
* @apiParam {String} image 租户图片
|
||||
* @apiParam {String} [remark="''"] 备注信息
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) EditPassword(c *gin.Context) {
|
||||
func (a *Tenant) Delete(c *gin.Context) {
|
||||
form := new(api.IDStringForm)
|
||||
|
||||
if err := api.Bind(form)(c); err != nil {
|
||||
api.APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant.NewInstance()(api.GetSession()(c).(*session.Admin)).Delete(form.Convert())
|
||||
api.APIResponse(err)(c)
|
||||
}
|
||||
|
||||
func (a *Tenant) Member(c *gin.Context) {
|
||||
form := &struct {
|
||||
idForm
|
||||
Password string `json:"password" form:"password" binding:"required"` // 登录密码
|
||||
RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd" binding:"required"` // 重复登录密码
|
||||
TenantID string `json:"tenant_id" form:"tenant_id" binding:"required"`
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
if err := api.Bind(form)(c); err != nil {
|
||||
api.APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).Edit(&tenant2.InstanceParams{ID: form.ID, Password: form.Password,
|
||||
RepeatPwd: form.RepeatPwd,
|
||||
})
|
||||
APIResponse(err)(c)
|
||||
data, err := tenant.NewMember()(api.GetSession()(c).(*session.Admin)).
|
||||
Instance((&api.IDStringForm{ID: form.TenantID}).Convert())
|
||||
api.APIResponse(err, data)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/detail 租户详细信息
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantDetail
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
* @apiParam {Number} type 详细信息(1:基本信息,2:资产设备信息,3:成员信息,4:权限信息)
|
||||
* @apiParam {Number} [current=0] 当前页
|
||||
* @apiParam {Number} [page_size=0] 页展示数
|
||||
* @apiParam {String} [name="''"] 成员名称
|
||||
* @apiParam {Number} [status=0] 成员状态
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": Any
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) Detail(c *gin.Context) {
|
||||
form := &struct {
|
||||
idForm
|
||||
Type tenant2.InstanceDetailType `json:"type" form:"type" binding:"required"`
|
||||
Page int `json:"current" form:"current"`
|
||||
PageSize int `json:"pageSize" form:"pageSize"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Status int `json:"status" form:"status"`
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
data, err := tenant2.NewInstance()(getSession()(c).(*service.Session)).Detail(form.ID, form.Type, form.Page,
|
||||
form.PageSize, form.Name, form.Status)
|
||||
APIResponse(err, data)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/renewal 租户续期
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantRenewal
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
* @apiParam {Time} deadline 协议有效期:2021-12-31
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) Renewal(c *gin.Context) {
|
||||
form := &struct {
|
||||
idForm
|
||||
Deadline string `json:"deadline" form:"deadline" binding:"required"`
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).Renewal(form.ID, form.Deadline)
|
||||
APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/start_up 租户启用
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantStartUp
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) StartUp(c *gin.Context) {
|
||||
form := new(idForm)
|
||||
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).StartUp(form.ID)
|
||||
APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/disable 租户禁用
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantDisable
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) Disable(c *gin.Context) {
|
||||
form := new(idForm)
|
||||
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).Disable(form.ID)
|
||||
APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/member/bind 租户用户绑定状态
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantMemberBind
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} id ID
|
||||
* @apiParam {Number} status 状态(1:启用,2:禁用)
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) MemberBind(c *gin.Context) {
|
||||
form := &struct {
|
||||
uidForm
|
||||
Status int `json:"status" form:"status" binding:"required"`
|
||||
TenantID string `json:"tenant_id" form:"tenant_id" binding:"required"`
|
||||
Mobile string `json:"mobile" form:"mobile" binding:"required"`
|
||||
Password string `json:"password" form:"password" binding:"required"`
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewInstance()(getSession()(c).(*service.Session)).MemberBind(form.Convert(), form.Status)
|
||||
err := tenant.NewMember()(api.GetSession()(c).(*session.Admin)).Form((&api.IDStringForm{ID: form.TenantID}).Convert(),
|
||||
&tenant.MemberParams{Mobile: form.Mobile, Password: form.Password})
|
||||
APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} /api/tenant/menu 菜单信息
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantMenu
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
* @apiSuccess (200) {Array} data 具体信息
|
||||
* @apiSuccess (200) {Number} data.id 菜单ID
|
||||
* @apiSuccess (200) {Number} data.parent_id 父级ID
|
||||
* @apiSuccess (200) {String} data.name 菜单名称
|
||||
* @apiSuccess (200) {Number} data.kind 类型(1:目录,2:菜单)
|
||||
* @apiSuccess (200) {String} data.link 访问地址
|
||||
* @apiSuccess (200) {String} data.component 组件
|
||||
* @apiSuccess (200) {Array} data.children="[]" 子集
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": [
|
||||
* "id": 1,
|
||||
* "parent_id": 0,
|
||||
* "name": "系统管理",
|
||||
* "kind": 1,
|
||||
* "link": "1"
|
||||
* "component": ""
|
||||
* "children": [
|
||||
* {
|
||||
* "id": 2,
|
||||
* "parent_id": 1,
|
||||
* "name": "用户管理",
|
||||
* "kind": 1,
|
||||
* "link": "1"
|
||||
* "component": ""
|
||||
* "children": [],
|
||||
* }
|
||||
* ]
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) Menu(c *gin.Context) {
|
||||
form := &struct {
|
||||
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"`
|
||||
@ -455,32 +115,10 @@ func (a *Tenant) Menu(c *gin.Context) {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
data, err := tenant2.NewMenu()(getSession()(c).(*service.Session)).List(form.TenantID)
|
||||
data, err := tenant.NewMenu()(getSession()(c).(*service.Session)).List(form.TenantID)
|
||||
APIResponse(err, data)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/menu/bind 菜单绑定
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantMenuBind
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} tenant_id 租户ID
|
||||
* @apiParam {Array.Number} menu_ids 菜单ID
|
||||
*
|
||||
* @apiSuccess (200) {Number} code=200 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg="ok" 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) MenuBind(c *gin.Context) {
|
||||
form := &struct {
|
||||
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"`
|
||||
@ -490,32 +128,10 @@ func (a *Tenant) MenuBind(c *gin.Context) {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewMenu()(getSession()(c).(*service.Session)).Bind(form.TenantID, form.MenuIDs)
|
||||
err := tenant.NewMenu()(getSession()(c).(*service.Session)).Bind(form.TenantID, form.MenuIDs)
|
||||
APIResponse(err)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/tenant/auth/bind 权限绑定
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName TenantAuthBind
|
||||
* @apiGroup Tenant
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {Number} tenant_id 租户ID
|
||||
* @apiParam {Array.Number} auth_ids 权限ID
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Tenant) AuthBind(c *gin.Context) {
|
||||
form := &struct {
|
||||
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"`
|
||||
@ -525,6 +141,6 @@ func (a *Tenant) AuthBind(c *gin.Context) {
|
||||
APIFailure(err.(error))(c)
|
||||
return
|
||||
}
|
||||
err := tenant2.NewAuth()(getSession()(c).(*service.Session)).Bind(form.TenantID, form.AuthIDs)
|
||||
err := tenant.NewAuth()(getSession()(c).(*service.Session)).Bind(form.TenantID, form.AuthIDs)
|
||||
APIResponse(err)(c)
|
||||
}
|
||||
|
@ -1,421 +1,131 @@
|
||||
package tenant
|
||||
|
||||
import (
|
||||
"SciencesServer/app/api/admin/controller"
|
||||
auth2 "SciencesServer/app/api/admin/controller/auth"
|
||||
menu2 "SciencesServer/app/api/admin/controller/menu"
|
||||
model3 "SciencesServer/app/api/admin/model"
|
||||
"SciencesServer/app/api/admin/model"
|
||||
"SciencesServer/app/basic/config"
|
||||
"SciencesServer/app/basic/controller"
|
||||
model2 "SciencesServer/app/common/model"
|
||||
"SciencesServer/app/service"
|
||||
"SciencesServer/config"
|
||||
"SciencesServer/serve/orm"
|
||||
"SciencesServer/app/session"
|
||||
config2 "SciencesServer/config"
|
||||
"SciencesServer/utils"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Instance struct{ *controller.Platform }
|
||||
type Instance struct {
|
||||
session *session.Admin
|
||||
}
|
||||
|
||||
type InstanceHandle func(session *service.Session) *Instance
|
||||
type InstanceHandle func(session *session.Admin) *Instance
|
||||
|
||||
type (
|
||||
// InstanceInfo 租户信息
|
||||
InstanceInfo struct {
|
||||
*model3.SysTenantInfo
|
||||
ID string `json:"id"`
|
||||
*model2.SysTenant
|
||||
}
|
||||
// InstanceParams 租户参数信息
|
||||
// InstanceParams 参数信息
|
||||
InstanceParams struct {
|
||||
ID uint64
|
||||
Image, Name, Account, Password, RepeatPwd string
|
||||
Deadline, Remark string
|
||||
ID uint64
|
||||
Name, Domain, Remark string
|
||||
Area config.Area
|
||||
Contact, ContactMobile 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
|
||||
)
|
||||
// Index 首页列表信息
|
||||
func (c *Instance) Index(name string, page, pageSize int) (*controller.ReturnPages, error) {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
out := make([]*model2.SysTenant, 0)
|
||||
|
||||
// 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 := model3.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: &model3.SysTenantInfo{
|
||||
SysTenant: mSysTenant.SysTenant,
|
||||
}}, nil
|
||||
where := []*model2.ModelWhereOrder{
|
||||
&model2.ModelWhereOrder{Order: model2.NewOrder("id", model2.OrderModeToDesc)},
|
||||
}
|
||||
}
|
||||
|
||||
// member 人员信息
|
||||
func member(id uint64) func(args ...interface{}) (interface{}, error) {
|
||||
return func(args ...interface{}) (interface{}, error) {
|
||||
mSysUserTenant := model3.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, Count: count}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// auth 权限信息
|
||||
func auth(id uint64) func(args ...interface{}) (interface{}, error) {
|
||||
return func(args ...interface{}) (interface{}, error) {
|
||||
mSysMenu := model3.NewSysMenu()
|
||||
|
||||
_menu, err := mSysMenu.TenantMenu(id)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mSysAuth := model3.NewSysAuth()
|
||||
|
||||
_auth := make([]*model3.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 := model3.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 := model3.NewSysTenant()
|
||||
|
||||
var count int64
|
||||
|
||||
where := []*model2.ModelWhere{model2.NewWhere("t.parent_id", 0)}
|
||||
|
||||
if name != "" {
|
||||
where = append(where, model2.NewWhereLike("t.name", name))
|
||||
where = append(where, &model2.ModelWhereOrder{Where: model2.NewWhereLike("name", name)})
|
||||
}
|
||||
if status > 0 {
|
||||
where = append(where, model2.NewWhere("t.status", status))
|
||||
}
|
||||
out, err := mSysTenant.Tenants(page, pageSize, &count, where...)
|
||||
var count int64
|
||||
|
||||
if err != nil {
|
||||
if err := model2.Pages(mSysTenant.SysTenant, &out, page, pageSize, &count, where...); 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})
|
||||
list = append(list, &InstanceInfo{
|
||||
ID: v.GetEncodeID(),
|
||||
SysTenant: v,
|
||||
})
|
||||
}
|
||||
return &controller.ReturnPages{Data: list, Count: count}, nil
|
||||
}
|
||||
|
||||
// Add 数据处理
|
||||
func (c *Instance) Add(params *InstanceParams) error {
|
||||
mSysTenant := model3.NewSysTenant()
|
||||
// Form 数据操作
|
||||
func (c *Instance) Form(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 params.ID > 0 {
|
||||
mSysTenant.ID = params.ID
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return errors.New("该租户/公司名称已存在")
|
||||
}
|
||||
mSysUser := model3.NewSysUser()
|
||||
isExist, err := model2.First(mSysTenant.SysTenant)
|
||||
|
||||
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.Remark = params.Remark
|
||||
|
||||
if err = model2.Create(mSysTenant.SysTenant, tx); err != nil {
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("操作错误,平台信息不存在或已被删除")
|
||||
}
|
||||
mSysUser.Name = mSysTenant.Name
|
||||
mSysUser.Account = params.Account
|
||||
mSysUser.Password = params.Password
|
||||
}
|
||||
mSysTenant.Name = params.Name
|
||||
mSysTenant.Area = model2.Area{
|
||||
Province: params.Area.Province,
|
||||
City: params.Area.City,
|
||||
}
|
||||
mSysTenant.Contact = params.Contact
|
||||
mSysTenant.ContactMobile = params.ContactMobile
|
||||
mSysTenant.Remark = params.Remark
|
||||
|
||||
if err = model2.Create(mSysUser.SysUser, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
mSysUserTenant := model3.NewSysUserTenant()
|
||||
mSysUserTenant.TenantID = mSysTenant.ID
|
||||
mSysUserTenant.UID = mSysUser.UUID
|
||||
mSysUserTenant.Identity = model2.SysUserTenantIdentityForSystemAdmin
|
||||
if mSysTenant.ID > 0 {
|
||||
return model2.Updates(mSysTenant.SysTenant, mSysTenant.SysTenant)
|
||||
}
|
||||
mSysTenant.Key = utils.GetRandomString(12)
|
||||
mSysTenant.Domain = params.Domain
|
||||
|
||||
if err = model2.Create(mSysUserTenant.SysUserTenant, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
if err := model2.Create(mSysTenant.SysTenant); err != nil {
|
||||
return err
|
||||
}
|
||||
_session := session.NewTenant()
|
||||
_session.ID = mSysTenant.ID
|
||||
_session.Name = mSysTenant.Name
|
||||
_session.Domain = mSysTenant.Domain
|
||||
|
||||
service.Publish(config2.EventForRedisHashProduce, config2.RedisKeyForTenant, _session.Domain, _session)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Edit 修改信息
|
||||
func (c *Instance) Edit(params *InstanceParams) error {
|
||||
mSysTenant := model3.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 := model3.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 := model3.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 := model3.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 := model3.NewSysTenant()
|
||||
// Delete 删除操作
|
||||
func (c *Instance) Delete(id uint64) error {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
mSysTenant.ID = id
|
||||
|
||||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||||
isExist, err := model2.FirstField(mSysTenant.SysTenant, []string{"id", "name", "domain"})
|
||||
|
||||
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("非法操作,不可续期他人客户使用期限")
|
||||
}
|
||||
return errors.New("操作错误,平台信息不存在或已被删除")
|
||||
}
|
||||
now := time.Now()
|
||||
|
||||
updates := make(map[string]interface{}, 0)
|
||||
updates["updated_at"] = now
|
||||
|
||||
if err = model2.Updates(mSysTenant.SysTenant, updates); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartUp 启用处理
|
||||
func (c *Instance) StartUp(id uint64) error {
|
||||
mSysTenant := model3.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("不可启用其他租户/公司客户")
|
||||
}
|
||||
}
|
||||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{}); 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 := model3.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 err := model2.Updates(mSysUserTenant.SysUserTenant, map[string]interface{}{
|
||||
"status": status, "updated_at": time.Now(),
|
||||
}); err != nil {
|
||||
if err = model2.Delete(mSysTenant.SysTenant); err != nil {
|
||||
return err
|
||||
}
|
||||
service.Publish(config2.EventForRedisHashDestroy, config2.RedisKeyForTenant, mSysTenant.Domain)
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewInstance() InstanceHandle {
|
||||
return func(session *service.Session) *Instance {
|
||||
return &Instance{Platform: &controller.Platform{Session: session}}
|
||||
return func(session *session.Admin) *Instance {
|
||||
return &Instance{
|
||||
session: session,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
81
app/api/admin/controller/tenant/member.go
Normal file
81
app/api/admin/controller/tenant/member.go
Normal file
@ -0,0 +1,81 @@
|
||||
package tenant
|
||||
|
||||
import (
|
||||
"SciencesServer/app/api/admin/model"
|
||||
model2 "SciencesServer/app/common/model"
|
||||
"SciencesServer/app/session"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Member 人员信息
|
||||
type Member struct {
|
||||
session *session.Admin
|
||||
}
|
||||
|
||||
type MemberHandle func(session *session.Admin) *Member
|
||||
|
||||
type (
|
||||
// MemberInfo 人员信息
|
||||
MemberInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Account string `json:"account"`
|
||||
Mobile string `json:"mobile"`
|
||||
}
|
||||
// MemberParams 人员参数信息
|
||||
MemberParams struct {
|
||||
Mobile, Password string
|
||||
}
|
||||
)
|
||||
|
||||
// Instance 人员信息
|
||||
func (c *Member) Instance(tenantID uint64) (*MemberInfo, error) {
|
||||
mSysUser := model.NewSysUser()
|
||||
|
||||
isExist, err := model2.FirstField(mSysUser.SysUser, []string{"id", "name", "account", "mobile"},
|
||||
model2.NewWhere("tenant_id", tenantID),
|
||||
model2.NewWhere("is_admin", model2.SysUserAdministratorForAdmin))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := new(MemberInfo)
|
||||
|
||||
if !isExist {
|
||||
goto RETURNS
|
||||
}
|
||||
out.ID = mSysUser.GetEncodeID()
|
||||
out.Name = mSysUser.Name
|
||||
out.Account = mSysUser.Account
|
||||
out.Mobile = mSysUser.Mobile
|
||||
RETURNS:
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Form 数据操作
|
||||
func (c *Member) Form(tenantID uint64, params *MemberParams) error {
|
||||
mSysUser := model.NewSysUser()
|
||||
|
||||
isExist, err := model2.FirstField(mSysUser.SysUser, []string{"id", "name", "account", "mobile"},
|
||||
model2.NewWhere("tenant_id", tenantID),
|
||||
model2.NewWhere("is_admin", model2.SysUserAdministratorForAdmin))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return errors.New("操作错误,当前平台已存在管理员")
|
||||
}
|
||||
mSysUser.TenantID = tenantID
|
||||
mSysUser.Account = params.Mobile
|
||||
mSysUser.Mobile = params.Mobile
|
||||
mSysUser.Password = params.Password
|
||||
mSysUser.IsAdmin = model2.SysUserAdministratorForAdmin
|
||||
|
||||
return model2.Create(mSysUser.SysUser)
|
||||
}
|
||||
|
||||
func NewMember() MemberHandle {
|
||||
return func(session *session.Admin) *Member {
|
||||
return &Member{session: session}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package tenant
|
||||
|
||||
import (
|
||||
model2 "SciencesServer/app/common/model"
|
||||
|
||||
"SciencesServer/config"
|
||||
"fmt"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Sub struct{}
|
||||
|
||||
type SubHandle func() *Sub
|
||||
|
||||
// database 数据表
|
||||
func (c *Sub) database(key string) string {
|
||||
return model2.SubDatabase + "_" + key
|
||||
}
|
||||
|
||||
// sync 同步数据
|
||||
func (c *Sub) sync(tx *gorm.DB, database string) error {
|
||||
// TODO:生成租户对应数据库,并生成对应数据表
|
||||
err := tx.Exec(fmt.Sprintf("CREATE DATABASE %s;", database)).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 使用生成后的数据库
|
||||
if err = tx.Exec(fmt.Sprintf("use %s;", database)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
iModels := []model2.IModel{}
|
||||
|
||||
for _, v := range iModels {
|
||||
if err = tx.Migrator().CreateTable(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 重新使用默认的数据库
|
||||
tx.Exec(fmt.Sprintf("use %s;", config.EngineInfo.Engines.Mysql.Database))
|
||||
|
||||
return nil
|
||||
}
|
@ -3,7 +3,6 @@ package model
|
||||
import (
|
||||
"SciencesServer/app/common/model"
|
||||
"SciencesServer/serve/orm"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SysTenant struct {
|
||||
@ -61,24 +60,6 @@ func (m *SysTenant) Tenants(page, pageSize int, count *int64, where ...*model.Mo
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TenantSubset 租户子集信息
|
||||
func (m *SysTenant) TenantSubset(tenantID uint64) ([]*SysTenantSubsetInfo, error) {
|
||||
|
||||
sql := fmt.Sprintf(`SELECT t3.id, t3.parent_id, t3.name, d.count AS device_count FROM
|
||||
(SELECT t1.id, t1.parent_id, t1.name, IF(FIND_IN_SET( parent_id, @pids ) > 0, @pids := concat( @pids, ',', id ), 0 ) AS is_child
|
||||
FROM (SELECT id, parent_id, name FROM %s WHERE is_deleted = 0 ORDER BY id DESC) AS t1,
|
||||
(SELECT @pids := %d) AS t2) AS t3
|
||||
LEFT JOIN (SELECT tenant_id, COUNT(id) AS count FROM %s WHERE is_deleted = 0 GROUP BY tenant_id) AS d ON t3.id = d.tenant_id
|
||||
WHERE is_child != 0`, m.TableName(), tenantID, "数据表")
|
||||
|
||||
out := make([]*SysTenantSubsetInfo, 0)
|
||||
|
||||
if err := orm.GetDB().Raw(sql).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewSysTenant() *SysTenant {
|
||||
return &SysTenant{SysTenant: model.NewSysTenant()}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
config2 "SciencesServer/app/basic/config"
|
||||
"SciencesServer/app/common/model"
|
||||
"SciencesServer/utils"
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@ -22,12 +23,16 @@ type synchronized struct {
|
||||
func (this *Instance) Handle() {
|
||||
db := this.gormDB
|
||||
|
||||
successCount, failureCount := 0, 0
|
||||
|
||||
function := func(synchronized ...*synchronized) {
|
||||
for _, v := range synchronized {
|
||||
if !db.Migrator().HasTable(v.iModel) {
|
||||
err := db.Migrator().CreateTable(v.iModel)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
successCount++
|
||||
} else {
|
||||
failureCount++
|
||||
}
|
||||
if v.iValues != nil && v.iValues() != nil {
|
||||
db.Table(v.iModel.TableName()).Create(v.iValues())
|
||||
@ -136,6 +141,7 @@ func (this *Instance) Handle() {
|
||||
&synchronized{iModel: model.NewActivityInstance()}, &synchronized{iModel: model.NewActivityApply()},
|
||||
&synchronized{iModel: model.NewActivityExamine()}, &synchronized{iModel: model.NewActivityJoin()},
|
||||
)
|
||||
fmt.Printf("========================\n=== 数据迁移,成功【%d】,失败【%d】 ===\n========================\n", successCount, failureCount)
|
||||
}
|
||||
|
||||
func WithGormDBOption(db *gorm.DB) Option {
|
||||
|
@ -1,21 +1,15 @@
|
||||
package model
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// SysTenant 租户数据管理模型
|
||||
type SysTenant struct {
|
||||
Model
|
||||
Key string `gorm:"column:key;type:varchar(30);default:'';comment:key" json:"key"`
|
||||
ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"-"`
|
||||
Image
|
||||
Name string `gorm:"column:name;type:varchar(30);default:'';comment:名称" json:"name"`
|
||||
Code string `gorm:"column:code;type:varchar(30);default:'';comment:信用代码" json:"code"`
|
||||
Images
|
||||
Key string `gorm:"column:key;type:varchar(30);default:'';comment:key" json:"key"`
|
||||
Name string `gorm:"column:name;type:varchar(30);default:'';comment:名称" json:"name"`
|
||||
Contact string `gorm:"column:contact;type:varchar(30);default:'';comment:联系人" json:"contact"`
|
||||
ContactMobile string `gorm:"column:contact_mobile;type:varchar(15);default:'';comment:联系方式" json:"contact_mobile"`
|
||||
Area
|
||||
Position string `gorm:"column:position;type:varchar(255);default:'';comment:坐标" json:"-"`
|
||||
Industry string `gorm:"column:industry;type:varchar(255);default:'';comment:所属领域;行业信息" json:"-"`
|
||||
Introduce string `gorm:"column:introduce;type:text;comment:介绍描述" json:"introduce"`
|
||||
Config string `gorm:"column:config;type:varchar(255);default:'';comment:配置信息" json:"-"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:'';comment:备注信息" json:"remark"`
|
||||
Domain string `gorm:"column:domain;type:varchar(255);default:'';comment:domain" json:"域名地址"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:'';comment:备注信息" json:"remark"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
@ -24,17 +18,6 @@ func (m *SysTenant) TableName() string {
|
||||
return "sys_tenant"
|
||||
}
|
||||
|
||||
func (m *SysTenant) GetIndustryAttribute() []string {
|
||||
out := make([]string, 0)
|
||||
_ = json.Unmarshal([]byte(m.Industry), &out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *SysTenant) SetIndustryAttribute(value []string) {
|
||||
_bytes, _ := json.Marshal(value)
|
||||
m.Industry = string(_bytes)
|
||||
}
|
||||
|
||||
func NewSysTenant() *SysTenant {
|
||||
return &SysTenant{}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func (this *Cache) Init() {
|
||||
}
|
||||
}
|
||||
function(
|
||||
&caches{iModel: model.NewSysTenant(), iValues: func() interface{} {
|
||||
&caches{iModel: model.NewSysConfig(), iValues: func() interface{} {
|
||||
out := make([]*model.SysConfig, 0)
|
||||
_ = model.Find(model.NewSysConfig(), &out)
|
||||
return out
|
||||
|
25
app/session/tenant.go
Normal file
25
app/session/tenant.go
Normal file
@ -0,0 +1,25 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"SciencesServer/utils"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Tenant 租户数据信息
|
||||
type Tenant struct {
|
||||
ID uint64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Domain string `json:"domain"`
|
||||
}
|
||||
|
||||
func (this *Tenant) MarshalBinary() ([]byte, error) {
|
||||
return json.Marshal(this)
|
||||
}
|
||||
|
||||
func (this *Tenant) UnmarshalBinary(data []byte) error {
|
||||
return utils.FromJSONBytes(data, this)
|
||||
}
|
||||
|
||||
func NewTenant() *Tenant {
|
||||
return &Tenant{}
|
||||
}
|
@ -15,6 +15,7 @@ import (
|
||||
"SciencesServer/utils"
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -69,13 +70,25 @@ func run() {
|
||||
// 开启Elasticsearch
|
||||
es.NewInstance(es.WithEsAddress([]string{config.SettingInfo.ESServer.Host})).Init().Local()
|
||||
// 开启web
|
||||
web.NewWeb()(&web.WebConfig{
|
||||
Port: config.SettingInfo.Server.Port, ReadTimeout: config.SettingInfo.Server.ReadTimeout,
|
||||
WriteTimeout: config.SettingInfo.Server.WriteTimeout, IdleTimeout: config.SettingInfo.Server.IdleTimeout,
|
||||
}).Run(router.NewRouter(&router.Option{
|
||||
Mode: config.Mode, IsCors: true,
|
||||
RateLimitConfig: &router.RateLimitConfig{
|
||||
IsRate: true, Limit: config.SettingInfo.Rate.Limit, Capacity: config.SettingInfo.Rate.Capacity,
|
||||
},
|
||||
}).Init())
|
||||
web.NewWeb(web.WithPort(config.SettingInfo.Server.Port),
|
||||
web.WithReadTimeout(config.SettingInfo.Server.ReadTimeout),
|
||||
web.WithWriteTimeout(config.SettingInfo.Server.WriteTimeout),
|
||||
web.WithIdleTimeout(config.SettingInfo.Server.IdleTimeout),
|
||||
web.WithHandler(router.NewRouter(&router.Option{
|
||||
Mode: config.Mode, IsCors: true,
|
||||
RateLimitConfig: &router.RateLimitConfig{
|
||||
IsRate: true, Limit: config.SettingInfo.Rate.Limit, Capacity: config.SettingInfo.Rate.Capacity,
|
||||
},
|
||||
}).Init()),
|
||||
web.WithFunction(func(src string) (bool, func(r *http.Request)) {
|
||||
value, _ := cache.Cache.HGet(config.RedisKeyForTenant, src)
|
||||
|
||||
if value == "" {
|
||||
return true, nil
|
||||
}
|
||||
return true, func(r *http.Request) {
|
||||
r.Header.Set("", value)
|
||||
}
|
||||
}),
|
||||
).Run()
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ const (
|
||||
|
||||
RedisKeyForAccountAdmin string = "account:admin"
|
||||
RedisKeyForAccountEnterprise string = "account:enterprise"
|
||||
RedisKeyForTenant string = "tenant:instance"
|
||||
RedisKeyForTenant string = "tenant"
|
||||
RedisKeyForTenantKeys string = "tenant:keys"
|
||||
)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package config
|
||||
|
||||
var SystemConfig = map[string]interface{}{}
|
||||
var SystemConfig = make(map[string]interface{}, 0)
|
||||
|
||||
//png,jpg,csv,xls,xlsx,pcm,wav,amr,mp3,mp4,json
|
||||
|
||||
|
@ -163,14 +163,11 @@ func registerAdminAPI(app *gin.Engine) {
|
||||
tenant := g.Group("/tenant")
|
||||
{
|
||||
_api := new(api1.Tenant)
|
||||
tenant.POST("/list", _api.List)
|
||||
tenant.POST("/", _api.Instance)
|
||||
tenant.POST("/add", _api.Add)
|
||||
tenant.POST("/edit", _api.Edit)
|
||||
tenant.POST("/edit/password", _api.EditPassword)
|
||||
tenant.POST("/detail", _api.Detail)
|
||||
tenant.POST("/renewal", _api.Renewal)
|
||||
tenant.POST("/start_up", _api.StartUp)
|
||||
tenant.POST("/disable", _api.Disable)
|
||||
tenant.POST("/delete", _api.Delete)
|
||||
tenant.POST("/member", _api.Member)
|
||||
tenant.POST("/member/bind", _api.MemberBind)
|
||||
tenant.POST("/menu", _api.Menu)
|
||||
tenant.POST("/menu/bind", _api.MenuBind)
|
||||
|
@ -3,6 +3,7 @@ package web
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
@ -10,15 +11,73 @@ import (
|
||||
)
|
||||
|
||||
type Web struct {
|
||||
*WebConfig
|
||||
httpServer *http.Server
|
||||
}
|
||||
|
||||
type WebConfig struct {
|
||||
Port, ReadTimeout, WriteTimeout, IdleTimeout int
|
||||
handler http.Handler
|
||||
function func(string) (bool, func(r *http.Request))
|
||||
}
|
||||
|
||||
type WebServer func(config *WebConfig) *Web
|
||||
type Option func(web *Web)
|
||||
|
||||
type Callback func(request *http.Request)
|
||||
|
||||
func WithPort(port int) Option {
|
||||
return func(web *Web) {
|
||||
web.Port = port
|
||||
}
|
||||
}
|
||||
|
||||
func WithReadTimeout(readTimeout int) Option {
|
||||
return func(web *Web) {
|
||||
web.ReadTimeout = readTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func WithWriteTimeout(writeTimeout int) Option {
|
||||
return func(web *Web) {
|
||||
web.WriteTimeout = writeTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func WithIdleTimeout(idleTimeout int) Option {
|
||||
return func(web *Web) {
|
||||
web.IdleTimeout = idleTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func WithHandler(handler http.Handler) Option {
|
||||
return func(web *Web) {
|
||||
web.handler = handler
|
||||
}
|
||||
}
|
||||
|
||||
func WithFunction(function func(string) (bool, func(r *http.Request))) Option {
|
||||
return func(web *Web) {
|
||||
web.function = function
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Web) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
remoteUrl, _ := url.Parse("http://192.168.0.147:9000")
|
||||
fmt.Println(remoteUrl)
|
||||
fmt.Println(r.Host)
|
||||
fmt.Println(r.RequestURI)
|
||||
|
||||
if this.function != nil {
|
||||
pass, callback := this.function(r.Host)
|
||||
|
||||
if !pass {
|
||||
_, _ = w.Write([]byte("403: Host forbidden"))
|
||||
return
|
||||
}
|
||||
if callback != nil {
|
||||
// 执行回调
|
||||
callback(r)
|
||||
}
|
||||
}
|
||||
//hostProxy[host] = proxy // 放入缓存
|
||||
//w.Write([]byte("403: Host forbidden " + r.Host))
|
||||
this.handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (this *Web) stop() {
|
||||
c := make(chan os.Signal)
|
||||
@ -38,10 +97,10 @@ func (this *Web) stop() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (this *Web) Run(handler http.Handler) {
|
||||
this.httpServer = &http.Server{
|
||||
func (this *Web) Run() {
|
||||
serve := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", this.Port),
|
||||
Handler: handler,
|
||||
Handler: this,
|
||||
ReadTimeout: time.Duration(this.ReadTimeout) * time.Second,
|
||||
WriteTimeout: time.Duration(this.WriteTimeout) * time.Second,
|
||||
IdleTimeout: time.Duration(this.IdleTimeout) * time.Second,
|
||||
@ -52,11 +111,14 @@ func (this *Web) Run(handler http.Handler) {
|
||||
fmt.Println("Http Server Start")
|
||||
fmt.Printf("Http Server Address - %v\n", fmt.Sprintf("http://127.0.0.1:%d", this.Port))
|
||||
|
||||
_ = this.httpServer.ListenAndServe()
|
||||
_ = serve.ListenAndServe()
|
||||
}
|
||||
|
||||
func NewWeb() WebServer {
|
||||
return func(config *WebConfig) *Web {
|
||||
return &Web{WebConfig: config}
|
||||
func NewWeb(options ...Option) *Web {
|
||||
out := &Web{Port: 80}
|
||||
|
||||
for _, option := range options {
|
||||
option(out)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
Reference in New Issue
Block a user