feat:完善项目信息

This commit is contained in:
henry
2022-01-05 16:09:55 +08:00
parent 822ced6041
commit 53c1f3912b
14 changed files with 352 additions and 922 deletions

View File

@ -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)
}

View File

@ -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,
}
}
}

View 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}
}
}

View File

@ -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
}

View File

@ -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()}
}

View File

@ -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 {

View File

@ -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{}
}

View File

@ -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
View 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{}
}

View File

@ -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()
}

View File

@ -8,7 +8,7 @@ const (
RedisKeyForAccountAdmin string = "account:admin"
RedisKeyForAccountEnterprise string = "account:enterprise"
RedisKeyForTenant string = "tenant:instance"
RedisKeyForTenant string = "tenant"
RedisKeyForTenantKeys string = "tenant:keys"
)

View File

@ -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

View File

@ -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)

View File

@ -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
}