feat:完善项目

This commit is contained in:
henry
2021-11-02 16:22:07 +08:00
parent 690cd96bed
commit 20d81825e1
81 changed files with 5394 additions and 3700 deletions

24
.gitignore vendored
View File

@ -1,26 +1,10 @@
# ---> Go
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
.idea/
log/
cmd/ctl/main
ArmedPolice

View File

@ -1,9 +1,7 @@
package api
import (
"ArmedPolice/app/controller"
"ArmedPolice/app/service"
"ArmedPolice/app/controller/account"
"github.com/gin-gonic/gin"
)
@ -52,8 +50,8 @@ func (a *Account) Login(c *gin.Context) {
APIFailure(err.(error))(c)
return
}
data, err := controller.NewAccount()(nil).Login(form.Account, form.Password, form.Captcha.Key, form.Captcha.Value,
c.GetHeader("x-equipment"), c.ClientIP())
//c.GetHeader("x-equipment")
data, err := account.NewInstance()(nil).Login()
APIResponse(err, data)(c)
}
@ -77,6 +75,6 @@ func (a *Account) Login(c *gin.Context) {
* }
*/
func (a *Account) Logout(c *gin.Context) {
err := controller.NewAccount()(getSession()(c).(*service.Session)).Logout()
APIResponse(err)(c)
//err := controller.NewAccount()(getSession()(c).(*service.Session)).Logout()
//APIResponse(err)(c)
}

View File

@ -1,101 +0,0 @@
package api
import (
"ArmedPolice/app/controller/auth"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
type Auth struct{}
/**
* @apiDefine Auth 权限管理
*/
func (a *Auth) List(c *gin.Context) {
data, err := auth.NewInstance()(getSession()(c).(*service.Session)).List()
APIResponse(err, data)(c)
}
/**
* @api {post} /api/auth/tenant/bind 租户权限绑定
* @apiVersion 1.0.0
* @apiName AuthTenantBind
* @apiGroup Auth
*
* @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 *Auth) TenantBind(c *gin.Context) {
form := &struct {
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"`
AuthIDs []uint64 `json:"auth_ids" form:"auth_ids" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := auth.NewTenant()(getSession()(c).(*service.Session)).Bind(form.TenantID, form.AuthIDs)
APIResponse(err)(c)
}
func (a *Auth) Role(c *gin.Context) {
form := &struct {
RoleID uint64 `json:"role_id" form:"role_id" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := auth.NewRole()(getSession()(c).(*service.Session)).List(form.RoleID)
APIResponse(err, data)(c)
}
/**
* @api {post} /api/auth/role/bind 角色权限绑定
* @apiVersion 1.0.0
* @apiName AuthRoleBind
* @apiGroup Auth
*
* @apiHeader {string} x-token token
*
* @apiParam {Number} role_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 *Auth) RoleBind(c *gin.Context) {
form := &struct {
RoleID uint64 `json:"role_id" form:"role_id" binding:"required"`
AuthIDs []uint64 `json:"auth_ids" form:"auth_ids" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := auth.NewRole()(getSession()(c).(*service.Session)).Bind(form.RoleID, form.AuthIDs)
APIResponse(err)(c)
}

View File

@ -1,34 +0,0 @@
package api
import (
"ArmedPolice/app/controller"
"github.com/gin-gonic/gin"
)
type Config struct{}
func (a *Config) List(c *gin.Context) {
form := &struct {
Kind int `json:"kind" form:"kind"`
pageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := controller.NewConfig()().Config(form.Kind, form.Page, form.PageSize)
APIResponse(err, data)
}
func (a *Config) Edit(c *gin.Context) {
form := &struct {
Params map[string]interface{} `json:"params" form:"params" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := controller.NewConfig()().Form(form.Params)
APIResponse(err)
}

View File

@ -1,23 +0,0 @@
package api
import (
"ArmedPolice/app/controller"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
type Log struct{}
func (a *Log) Login(c *gin.Context) {
form := &struct {
Name string `json:"name" form:"name"`
pageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := controller.NewLog()(getSession()(c).(*service.Session)).Login(form.Name, form.Page, form.PageSize)
APIResponse(err, data)(c)
}

View File

@ -1,425 +0,0 @@
package api
import (
"ArmedPolice/app/controller/menu"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
type Menu struct{}
type (
// menuForm 菜单信息
menuForm struct {
ParentID uint64 `json:"parent_id" form:"parent_id"`
Name string `json:"name" form:"name" binding:"required"`
Kind int `json:"kind" form:"kind" binding:"required"`
Link string `json:"link" form:"link"`
Component string `json:"component" form:"component"`
Icon string `json:"icon" form:"icon"`
Auth int `json:"auth" form:"auth"`
Sort int `json:"sort" form:"sort"`
Status int `json:"status" form:"status"`
Remark string `json:"remark" form:"remark"`
}
)
/**
* @apiDefine Menu 菜单管理
*/
/**
* @api {get} /api/menu/list 菜单列表
* @apiVersion 1.0.0
* @apiName MenuList
* @apiGroup Menu
*
* @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 *Menu) List(c *gin.Context) {
data, err := menu.NewInstance()(getSession()(c).(*service.Session)).List()
APIResponse(err, data)(c)
}
/**
* @api {post} /api/menu/add 菜单添加
* @apiVersion 1.0.0
* @apiName MenuAdd
* @apiGroup Menu
*
* @apiHeader {string} x-token token
*
* @apiParam {Number} parent_id 父级ID
* @apiParam {String} name 菜单名
* @apiParam {Number} kind 菜单类型1目录2菜单
* @apiParam {String} link 访问地址
* @apiParam {String} component 页面组件
* @apiParam {String} icon 页面icon
* @apiParam {Number} auth 菜单权限0普通权限1超管权限
* @apiParam {Number} sort 排序,从大到小
* @apiParam {Number} status 忘了干嘛,没用
* @apiParam {String} remark 备注信息
*
* @apiSuccess (200) {Number} code 成功响应状态码!
* @apiSuccess (200) {String} msg 成功提示
*
* @apiSuccessExample {json} Success response:
* HTTPS 200 OK
* {
* "code": 200
* "msg": "ok"
* }
*/
func (a *Menu) Add(c *gin.Context) {
form := new(menuForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := menu.NewInstance()(getSession()(c).(*service.Session)).Data(&menu.InstanceParams{
ParentID: form.ParentID, Name: form.Name, Kind: form.Kind, Link: form.Link, Component: form.Component,
Icon: form.Icon, Auth: form.Auth, Sort: form.Sort, Status: form.Status, Remark: form.Remark,
})
APIResponse(err)(c)
}
/**
* @api {post} /api/menu/edit 菜单修改
* @apiVersion 1.0.0
* @apiName MenuEdit
* @apiGroup Menu
*
* @apiHeader {string} x-token token
*
* @apiParam {Number} id ID
* @apiParam {Number} parent_id 父级ID
* @apiParam {String} name 菜单名
* @apiParam {Number} kind 菜单类型1目录2菜单
* @apiParam {String} link 访问地址
* @apiParam {String} component 页面组件
* @apiParam {String} icon 页面icon
* @apiParam {Number} auth 菜单权限0普通权限1超管权限
* @apiParam {Number} sort 排序,从大到小
* @apiParam {Number} status 禁用状态1启用2禁用
* @apiParam {String} remark 备注信息
*
* @apiSuccess (200) {Number} code 成功响应状态码!
* @apiSuccess (200) {String} msg 成功提示
*
* @apiSuccessExample {json} Success response:
* HTTPS 200 OK
* {
* "code": 200
* "msg": "ok"
* }
*/
func (a *Menu) Edit(c *gin.Context) {
form := &struct {
idForm
menuForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := menu.NewInstance()(getSession()(c).(*service.Session)).Data(&menu.InstanceParams{
ID: form.ID, ParentID: form.ParentID, Name: form.Name, Kind: form.Kind, Link: form.Link, Component: form.Component,
Icon: form.Icon, Auth: form.Auth, Sort: form.Sort, Status: form.Status, Remark: form.Remark,
})
APIResponse(err)(c)
}
/**
* @api {post} /api/menu/status 菜单状态
* @apiVersion 1.0.0
* @apiName MenuStatus
* @apiGroup Menu
*
* @apiHeader {string} x-token token
*
* @apiParam {Number} id ID
* @apiParam {Number} status 状态1启动2禁用
*
* @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 *Menu) Status(c *gin.Context) {
form := &struct {
idForm
Status int `json:"status" form:"status" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := menu.NewInstance()(getSession()(c).(*service.Session)).Status(form.ID, form.Status)
APIResponse(err)(c)
}
/**
* @api {post} /api/menu/delete 删除菜单
* @apiVersion 1.0.0
* @apiName MenuDelete
* @apiGroup Menu
*
* @apiHeader {string} x-token token
*
* @apiParam {Number} id 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 *Menu) Delete(c *gin.Context) {
form := new(idForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := menu.NewInstance()(getSession()(c).(*service.Session)).Delete(form.ID)
APIResponse(err)(c)
}
/**
* @api {get} /api/menu/user 用户菜单列表
* @apiVersion 1.0.0
* @apiName MenuUser
* @apiGroup Menu
*
* @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 *Menu) User(c *gin.Context) {
data, err := menu.NewUser()(getSession()(c).(*service.Session)).List()
APIResponse(err, data)(c)
}
func (a *Menu) Tenant(c *gin.Context) {
form := &struct {
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := menu.NewTenant()(getSession()(c).(*service.Session)).List(form.TenantID)
APIResponse(err, data)(c)
}
/**
* @api {post} /api/tenant/bind 租户菜单绑定
* @apiVersion 1.0.0
* @apiName MenuTenantBind
* @apiGroup Menu
*
* @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 *Menu) TenantBind(c *gin.Context) {
form := &struct {
TenantID uint64 `json:"tenant_id" form:"tenant_id" binding:"required"`
MenuIDs []uint64 `json:"menu_ids" form:"menu_ids" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := menu.NewTenant()(getSession()(c).(*service.Session)).Bind(form.TenantID, form.MenuIDs)
APIResponse(err)(c)
}
/**
* @api {post} /api/menu/role 角色菜单列表
* @apiVersion 1.0.0
* @apiName MenuRole
* @apiGroup Menu
*
* @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 *Menu) Role(c *gin.Context) {
form := &struct {
RoleID uint64 `json:"role_id" form:"role_id" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := menu.NewRole()(getSession()(c).(*service.Session)).List(form.RoleID)
APIResponse(err, data)(c)
}
/**
* @api {post} /api/role/bind 角色菜单绑定
* @apiVersion 1.0.0
* @apiName MenuRoleBind
* @apiGroup Menu
*
* @apiHeader {string} x-token token
*
* @apiParam {Number} role_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 *Menu) RoleBind(c *gin.Context) {
form := &struct {
RoleID uint64 `json:"role_id" form:"role_id" binding:"required"`
MenuIDs []uint64 `json:"menu_ids" form:"menu_ids" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := menu.NewRole()(getSession()(c).(*service.Session)).Bind(form.RoleID, form.MenuIDs)
APIResponse(err)(c)
}

View File

@ -1,107 +0,0 @@
package api
import (
"ArmedPolice/app/controller/role"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
type Role struct{}
func (a *Role) List(c *gin.Context) {
form := &struct {
Name string `json:"name" form:"name"`
Status int `json:"status" form:"status"`
pageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := role.NewInstance()(getSession()(c).(*service.Session)).List(form.Name, form.Status, form.Page, form.PageSize)
APIResponse(err, data)(c)
}
func (a *Role) Select(c *gin.Context) {
data, err := role.NewInstance()(getSession()(c).(*service.Session)).Select()
APIResponse(err, data)(c)
}
func (a *Role) Add(c *gin.Context) {
form := &struct {
Name string `json:"name" form:"name" binding:"required"`
Remark string `json:"remark" form:"remark" binding:"required"`
Sort int `json:"sort" form:"sort"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := role.NewInstance()(getSession()(c).(*service.Session)).Data(0, form.Name, form.Remark, form.Sort)
APIResponse(err)(c)
}
func (a *Role) Edit(c *gin.Context) {
form := &struct {
idForm
Name string `json:"name" form:"name" binding:"required"`
Remark string `json:"remark" form:"remark" binding:"required"`
Sort int `json:"sort" form:"sort"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := role.NewInstance()(getSession()(c).(*service.Session)).Data(form.ID, form.Name, form.Remark, form.Sort)
APIResponse(err)(c)
}
func (a *Role) Status(c *gin.Context) {
form := &struct {
idForm
Status int `json:"status" form:"status" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := role.NewInstance()(getSession()(c).(*service.Session)).Status(form.ID, form.Status)
APIResponse(err)(c)
}
func (a *Role) Delete(c *gin.Context) {
form := new(idForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := role.NewInstance()(getSession()(c).(*service.Session)).Delete(form.ID)
APIResponse(err)(c)
}
func (a *Role) User(c *gin.Context) {
form := &struct {
uidForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := role.NewUser()(getSession()(c).(*service.Session)).List(form.Convert())
APIResponse(err, data)(c)
}
func (a *Role) UserBind(c *gin.Context) {
form := &struct {
uidForm
RoleIDs []uint64 `json:"role_ids" form:"role_ids" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := role.NewUser()(getSession()(c).(*service.Session)).Bind(form.Convert(), form.RoleIDs)
APIResponse(err)(c)
}

View File

@ -6,32 +6,43 @@ import (
"strings"
)
type idForm struct {
type IDForm struct {
ID uint64 `json:"id" form:"id" binding:"required"`
}
type uidForm struct {
type IDStringForm struct {
ID string `json:"id" form:"id"`
}
func (this *IDStringForm) Convert() uint64 {
if this.ID == "" {
return 0
}
return uint64(utils.HASHIDDecode(this.ID))
}
type UIDForm struct {
UID string `json:"uid" form:"uid" binding:"required"`
}
func (this *uidForm) Convert() uint64 {
func (this *UIDForm) Convert() uint64 {
return utils.StringToUnit64(this.UID)
}
type imageForm struct {
type ImageForm struct {
Image string `json:"image" form:"image"`
}
func (this *imageForm) FilterImageURL() string {
func (this *ImageForm) FilterImageURL() string {
return strings.Replace(this.Image, config.SettingInfo.Domain, "", -1)
}
type positionForm struct {
type PositionForm struct {
Longitude float64 `json:"longitude" form:"longitude" binding:"required"`
Latitude float64 `json:"latitude" form:"latitude" binding:"required"`
}
type pageForm struct {
type PageForm struct {
Page int `json:"current" form:"current" binding:"required"`
PageSize int `json:"pageSize" form:"pageSize" binding:"required"`
PageSize int `json:"page_size" form:"page_size" binding:"required"`
}

132
app/api/supplier.go Normal file
View File

@ -0,0 +1,132 @@
package api
import (
"ArmedPolice/app/common/model"
"ArmedPolice/app/controller/supplier"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
type Supplier struct{}
type (
// supplierForm 参数信息
supplierForm struct {
Name string `json:"name" form:"name" binding:"required"`
Mobile string `json:"mobile" form:"mobile" binding:"required"`
Address string `json:"address" form:"address"`
Remark string `json:"remark" form:"remark"`
}
)
func (*Supplier) Material(c *gin.Context) {
form := &struct {
Name string `json:"name" form:"name"`
Mobile string `json:"mobile" form:"mobile"`
PageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := supplier.NewInstance()(getSession()(c).(*service.Session)).
List(form.Name, form.Mobile, model.ManageSupplierKindForMaterial, form.Page, form.PageSize)
APIResponse(err, data)
}
func (*Supplier) MaterialAdd(c *gin.Context) {
form := new(supplierForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := supplier.NewInstance()(getSession()(c).(*service.Session)).Form(&supplier.InstanceParams{
Name: form.Name, Mobile: form.Mobile, Address: form.Address, Remark: form.Remark,
Kind: model.ManageSupplierKindForMaterial,
})
APIResponse(err)
}
func (*Supplier) MaterialEdit(c *gin.Context) {
form := &struct {
IDStringForm
supplierForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := supplier.NewInstance()(getSession()(c).(*service.Session)).Form(&supplier.InstanceParams{
ID: form.Convert(), Name: form.Name, Mobile: form.Mobile, Address: form.Address, Remark: form.Remark,
Kind: model.ManageSupplierKindForMaterial,
})
APIResponse(err)
}
func (*Supplier) MaterialDelete(c *gin.Context) {
form := new(IDStringForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := supplier.NewInstance()(getSession()(c).(*service.Session)).Delete(form.Convert())
APIResponse(err)
}
func (*Supplier) Repair(c *gin.Context) {
form := &struct {
Name string `json:"name" form:"name"`
Mobile string `json:"mobile" form:"mobile"`
PageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := supplier.NewInstance()(getSession()(c).(*service.Session)).
List(form.Name, form.Mobile, model.ManageSupplierKindForRepair, form.Page, form.PageSize)
APIResponse(err, data)
}
func (*Supplier) RepairAdd(c *gin.Context) {
form := new(supplierForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := supplier.NewInstance()(getSession()(c).(*service.Session)).Form(&supplier.InstanceParams{
Name: form.Name, Mobile: form.Mobile, Address: form.Address, Remark: form.Remark,
Kind: model.ManageSupplierKindForRepair,
})
APIResponse(err)
}
func (*Supplier) RepairEdit(c *gin.Context) {
form := &struct {
IDStringForm
supplierForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := supplier.NewInstance()(getSession()(c).(*service.Session)).Form(&supplier.InstanceParams{
ID: form.Convert(), Name: form.Name, Mobile: form.Mobile, Address: form.Address, Remark: form.Remark,
Kind: model.ManageSupplierKindForRepair,
})
APIResponse(err)
}
func (*Supplier) RepairDelete(c *gin.Context) {
form := new(IDStringForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := supplier.NewInstance()(getSession()(c).(*service.Session)).Delete(form.Convert())
APIResponse(err)
}

View File

@ -1,403 +0,0 @@
package api
import (
"ArmedPolice/app/controller/tenant"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
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"` // 允许最多的客户数
}
)
/**
* @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) {
form := &struct {
Name string `json:"name" form:"name"`
Status int `json:"status" form:"status"`
pageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := tenant.NewInstance()(getSession()(c).(*service.Session)).List(form.Name, form.Status, form.Page, form.PageSize)
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)
return
}
err := tenant.NewInstance()(getSession()(c).(*service.Session)).Add(&tenant.InstanceParams{Name: form.Name,
Image: form.FilterImageURL(), Account: form.Account, Password: form.Password, RepeatPwd: form.RepeatPwd,
Deadline: form.Deadline, Remark: form.Remark,
})
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"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := tenant.NewInstance()(getSession()(c).(*service.Session)).Edit(&tenant.InstanceParams{ID: form.ID, Name: form.Name,
Image: form.FilterImageURL(), Remark: form.Remark,
})
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) {
form := &struct {
idForm
Password string `json:"password" form:"password" binding:"required"` // 登录密码
RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd" binding:"required"` // 重复登录密码
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := tenant.NewInstance()(getSession()(c).(*service.Session)).Edit(&tenant.InstanceParams{ID: form.ID, Password: form.Password,
RepeatPwd: form.RepeatPwd,
})
APIResponse(err)(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 tenant.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 := tenant.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 := tenant.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 := tenant.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 := tenant.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"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := tenant.NewInstance()(getSession()(c).(*service.Session)).MemberBind(form.Convert(), form.Status)
APIResponse(err)(c)
}

View File

@ -1,115 +1 @@
package api
import (
"ArmedPolice/app/controller/user"
"ArmedPolice/app/service"
"github.com/gin-gonic/gin"
)
type User struct{}
type userForm struct {
Account string `json:"account" form:"account" binding:"required"`
Name string `json:"name" form:"name" binding:"required"`
Mobile string `json:"mobile" form:"mobile" binding:"required"`
Gender int `json:"gender" form:"gender" binding:"required"`
Departments []uint64 `json:"departments" form:"departments"`
Roles []uint64 `json:"roles" form:"roles"`
Remark string `json:"remark" form:"remark"`
}
/**
* @apiDefine User 用户管理
*/
func (a *User) Info(c *gin.Context) {
data, err := user.NewInstance()(getSession()(c).(*service.Session)).Info()
APIResponse(err, data)(c)
}
func (a *User) List(c *gin.Context) {
form := &struct {
Name string `json:"name" form:"name"`
Mobile string `json:"mobile" form:"mobile"`
Status int `json:"status" form:"status"`
pageForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
data, err := user.NewInstance()(getSession()(c).(*service.Session)).List(form.Name, form.Mobile, form.Status, form.Page, form.PageSize)
APIResponse(err, data)(c)
}
func (a *User) Add(c *gin.Context) {
form := &struct {
userForm
Password string `json:"password" form:"password" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := user.NewInstance()(getSession()(c).(*service.Session)).Add(&user.InstanceForm{
Account: form.Account, Name: form.Name, Mobile: form.Mobile, Password: form.Password,
Remark: form.Remark, Gender: form.Gender, Departments: form.Departments, Roles: form.Roles,
})
APIResponse(err)(c)
}
func (a *User) Edit(c *gin.Context) {
form := &struct {
idForm
userForm
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := user.NewInstance()(getSession()(c).(*service.Session)).Edit(&user.InstanceForm{
ID: form.ID, Account: form.Account, Name: form.Name, Mobile: form.Mobile,
Remark: form.Remark, Gender: form.Gender, Departments: form.Departments, Roles: form.Roles,
})
APIResponse(err)(c)
}
func (a *User) Password(c *gin.Context) {
form := &struct {
idForm
Password string `json:"password" form:"password" binding:"required"`
RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := user.NewInstance()(getSession()(c).(*service.Session)).Password(form.ID, form.Password, form.RepeatPwd)
APIResponse(err)(c)
}
func (a *User) EditPassword(c *gin.Context) {
form := &struct {
OldPwd string `json:"old_pwd" form:"old_pwd" binding:"required"`
Password string `json:"password" form:"password" binding:"required"`
RepeatPwd string `json:"repeat_pwd" form:"repeat_pwd" binding:"required"`
}{}
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := user.NewPerson()(getSession()(c).(*service.Session)).EditPassword(form.OldPwd, form.Password, form.RepeatPwd)
APIResponse(err)(c)
}
func (a *User) Delete(c *gin.Context) {
form := new(idForm)
if err := bind(form)(c); err != nil {
APIFailure(err.(error))(c)
return
}
err := user.NewInstance()(getSession()(c).(*service.Session)).Delete(form.ID)
APIResponse(err)(c)
}

View File

@ -39,7 +39,7 @@ func initModel() {
&synchronized{iModel: model.NewSysConfig()},
&synchronized{iModel: model.NewSysMenu()}, &synchronized{iModel: model.NewSysAuth()},
&synchronized{iModel: model.NewSysUser(), iValues: func() interface{} {
return &model.SysUser{Account: "admin", Name: "商挈智能", Mobile: "13888888888", Password: "123456",
return &model.SysUser{Account: "admin", Name: "超级管理员", Mobile: "13888888888", Password: "123456",
IsAdmin: model.SysUserAdministratorForAdmin, Remark: "超级管理员"}
}},
&synchronized{iModel: model.NewSysUserTenant()},
@ -48,6 +48,8 @@ func initModel() {
&synchronized{iModel: model.NewSysUserRole()},
// 日志管理
&synchronized{iModel: model.NewSysLog()}, &synchronized{iModel: model.NewSysUserLoginLog()},
// 功能信息
&synchronized{iModel: model.NewManageSupplier()},
)
}
func initCacheMode() {

View File

@ -1,7 +1,9 @@
package model
import (
"ArmedPolice/config"
"ArmedPolice/utils"
"strings"
)
type Gender struct {
@ -51,6 +53,30 @@ func (m *Images) AnalysisSlice(domain string) []string {
return images
}
type Area struct {
Province string `gorm:"column:province;type:varchar(8);default:null;comment:所在省" json:"province"`
City string `gorm:"column:city;type:varchar(8);default:null;comment:所在市" json:"city"`
District string `gorm:"column:district;type:varchar(8);default:null;comment:所在区/县" json:"district"`
Address string `gorm:"column:address;type:varchar(255);default:null;comment:详细地址" json:"address"`
}
func (m *Area) FormatBasic() string {
address := make([]string, 0)
address = append(address, config.SettingAreaInfo[config.DefaultChinaAreaCode][m.Province])
if m.City != "" {
address = append(address, config.SettingAreaInfo[m.Province][m.City])
}
if m.District != "" {
address = append(address, config.SettingAreaInfo[m.City][m.District])
}
return strings.Join(address, "-")
}
func (m *Area) FormatDetail() string {
return m.FormatBasic() + "" + m.Address
}
// Position 坐标信息
type Position struct {
Longitude float64 `json:"longitude"` // 经度

View File

@ -0,0 +1,16 @@
package model
type ManageEquipment struct {
Model
ModelTenant
ModelDeleted
ModelAt
}
func (m *ManageEquipment) TableName() string {
return "manage_equipment"
}
func NewManageEquipment() *ManageEquipment {
return &ManageEquipment{}
}

View File

@ -0,0 +1,32 @@
package model
// ManageSupplier 供应商数据模型
type ManageSupplier struct {
Model
ModelTenant
Kind ManageSupplierKind `gorm:"column:kind;type:tinyint(1);default:1;comment:类型" json:"kind"`
Name string `gorm:"column:name;type:varchar(100);default:null;comment:名称" json:"name"`
Mobile string `gorm:"column:mobile;type:varchar(20);default:null;comment:联系方式" json:"mobile"`
Address string `gorm:"column:address;type:varchar(255);default:null;comment:联系地址" json:"address"`
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:备注信息 " json:"remark"`
ModelDeleted
ModelAt
}
// ManageSupplierKind 供应商类型
type ManageSupplierKind int
const (
// ManageSupplierKindForMaterial 材料供应商
ManageSupplierKindForMaterial ManageSupplierKind = iota + 101
// ManageSupplierKindForRepair 维修供应商
ManageSupplierKindForRepair
)
func (*ManageSupplier) TableName() string {
return "manage_supplier"
}
func NewManageSupplier() *ManageSupplier {
return &ManageSupplier{}
}

View File

@ -2,6 +2,7 @@ package model
import (
"ArmedPolice/serve/orm"
"ArmedPolice/utils"
"fmt"
"strings"
"time"
@ -12,13 +13,14 @@ import (
// IModel
type IModel interface {
GetID() uint64
GetEncodeID() string
TableName() string
SetDatabase(database string, key ...string)
}
// Model
type Model struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement;comment:主键" json:"id" form:"id"`
ID uint64 `gorm:"column:id;primaryKey;autoIncrement;comment:主键" json:"-" form:"id"`
Database string `json:"-" gorm:"-"`
}
@ -58,14 +60,14 @@ const (
FieldsForDeleted string = "is_deleted"
)
const (
SubDatabase string = "tenant"
)
func (m *Model) GetID() uint64 {
return m.ID
}
func (m *Model) GetEncodeID() string {
return utils.HASHIDEncode(int(m.ID))
}
func (m *Model) SetDatabase(database string, key ...string) {
m.Database = database + "_" + strings.Join(key, "_")
}

View File

@ -7,39 +7,18 @@ import (
"gorm.io/gorm"
)
// SysTenant 租户信息数据模型
type SysTenant struct {
Model
ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"-"`
Key string `gorm:"column:key;type:varchar(100);default:null;comment:租户/租户客户标识" json:"key"`
Image
Name string `gorm:"column:name;type:varchar(30);default:null;comment:租户名称/租户客户名称" json:"name"`
Config string `gorm:"column:config;type:text;comment:租户/租户客户配置信息" json:"-"`
Deadline time.Time `gorm:"column:deadline;type:datetime;default:null;comment:租户/租户客户协议截止时间" json:"deadline"`
Status SysTenantStatus `gorm:"column:status;type:tinyint(1);default:1;comment:租户/租户客户状态" json:"status"`
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:租户/租户客户备注" json:"remark"`
Key string `gorm:"column:key;type:varchar(100);default:null;comment:标识" json:"key"`
Name string `gorm:"column:name;type:varchar(30);default:null;comment:名称" json:"name"`
Area
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:备注信息" json:"remark"`
ModelDeleted
ModelAt
}
type SysTenantConfig struct {
MaxDevices int `json:"max_devices"` // 最大可连接设备数
MaxCustomer int `json:"max_customer"` // 最大可拥有的客户数
Protocol uint `json:"protocol"` // 支持的协议模式
}
type SysTenantStatus int
const (
// SysTenantStatusForNormal 正常
SysTenantStatusForNormal SysTenantStatus = iota + 1
// SysTenantStatusForWellExpire 协议将到期
SysTenantStatusForWellExpire
// SysTenantStatusForExpired 协议已过期
SysTenantStatusForExpired
// SysTenantStatusForDisable 已禁用
SysTenantStatusForDisable
)
func (m *SysTenant) TableName() string {
return "sys_tenant"
}
@ -51,19 +30,6 @@ func (m *SysTenant) BeforeCreate(db *gorm.DB) error {
return nil
}
func (m *SysTenant) ConfigInfo() *SysTenantConfig {
config := new(SysTenantConfig)
_ = utils.FromJSON(m.Config, config)
return config
}
func (m *SysTenant) StatusTitle() string {
if m.Status == SysTenantStatusForDisable {
return "禁用"
}
return "正常"
}
func NewSysTenant() *SysTenant {
return &SysTenant{}
}

View File

@ -1,17 +0,0 @@
package model
type SysTenantAuth struct {
Model
ModelTenant
AuthID uint64 `gorm:"column:auth_id;type:int;default:0;comment:权限ID" json:"-"`
ModelDeleted
ModelAt
}
func (m *SysTenantAuth) TableName() string {
return m.NewTableName("sys_tenant_auth")
}
func NewSysTenantAuth() *SysTenantAuth {
return &SysTenantAuth{}
}

View File

@ -1,17 +0,0 @@
package model
type SysTenantMenu struct {
Model
ModelTenant
MenuID uint64 `gorm:"column:menu_id;type:int;default:0;comment:菜单ID" json:"-"`
ModelDeleted
ModelAt
}
func (m *SysTenantMenu) TableName() string {
return m.NewTableName("sys_tenant_menu")
}
func NewSysTenantMenu() *SysTenantMenu {
return &SysTenantMenu{}
}

View File

@ -2,7 +2,6 @@ package model
import (
"ArmedPolice/utils"
"fmt"
"time"
"gorm.io/gorm"
@ -10,6 +9,7 @@ import (
type SysUser struct {
Model
ModelTenant
UUID uint64 `gorm:"column:uuid;uniqueIndex:idx_sys_user_uuid;type:int;default:0;comment:用户唯一UUID" json:"-"`
Account string `gorm:"column:account;type:varchar(50);default:null;comment:账户名" json:"account"`
Avatar string `gorm:"column:avatar;type:varchar(255);default:null;comment:头像" json:"avatar"`
@ -51,10 +51,6 @@ func (m *SysUser) Pass() {
m.Password = utils.HashString([]byte(utils.Md5String(m.Password, m.Salt)))
}
func (m *SysUser) UUIDString() string {
return fmt.Sprintf("%d", m.UUID)
}
func NewSysUser() *SysUser {
return &SysUser{}
}

View File

@ -1,100 +0,0 @@
package controller
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/handle"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/config"
"ArmedPolice/utils"
"errors"
)
type Account struct{ *Platform }
type AccountHandle func(session *service.Session) *Account
// Login 登录请求
func (c *Account) Login(account, password, captchaKey, captchaValue, equipment, ip string) (interface{}, error) {
return nil, errors.New("测试错误")
// 验证验证码
if pass, _ := handle.NewCaptcha().Validate(&handle.CaptchaImage{Key: captchaKey, Captcha: captchaValue}); !pass {
return nil, errors.New("验证码错误")
}
mSysUser := model.NewSysUser()
isExist, err := mSysUser.GetByAccountOrMobile(account)
if err != nil {
return nil, err
} else if !isExist {
return nil, errors.New("该帐号信息不存在")
}
if !mSysUser.ValidatePassword(password) {
return nil, errors.New("密码错误")
}
session := service.NewSession()
// 非超级管理员
if !session.IsAdmin {
// 查询相应关系
mSysUserTenant := model.NewSysUserTenant()
if isExist, err = model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity", "status"},
model2.NewWhere("uid", mSysUser.UUID)); err != nil {
return nil, err
} else if !isExist {
return nil, errors.New("当前不属于任何租户,不可登录")
} else if mSysUserTenant.Status != model2.SysUserTenantStatusForEnable {
return nil, errors.New("当前账号已禁用,不可登录,请联系管理员!")
}
if mSysUserTenant.TenantID <= 0 {
goto Complete
}
mSysTenant := model.NewSysTenant()
mSysTenant.ID = mSysUserTenant.TenantID
level := 0
for {
if isExist, err = model2.FirstField(mSysTenant, []string{"id", "key", "parent_id", "deadline", "status"}); err != nil {
return nil, err
} else if !isExist {
return nil, errors.New("租户信息不存在,不可登录")
} else if mSysTenant.IsInvalid() {
return nil, errors.New("租户协议已失效,不可登录")
}
if level <= 0 {
session.TenantID = mSysTenant.ID
session.TenantKey = mSysTenant.Key
}
// 判断是否含有含有上级
if mSysTenant.ParentID <= 0 {
goto Complete
}
level++
mSysTenant.ID = mSysTenant.ParentID
}
}
Complete:
uid := mSysUser.UUIDString()
session.Token = utils.JWTEncrypt(config.SettingInfo.TokenEffectTime, map[string]interface{}{config.TokenForUID: uid})
service.Publish(config.EventForRedisHashProduce, config.RedisKeyForAccount, uid, session)
service.Publish(config.EventForAccountLoginProduce, session.TenantID, session.UID, equipment, ip)
return session.Token, nil
}
// Logout 退出请求
func (c *Account) Logout() error {
service.Publish(config.EventForRedisHashDestroy, config.RedisKeyForAccount, utils.UintToString(c.UID))
return nil
}
func NewAccount() AccountHandle {
return func(session *service.Session) *Account {
return &Account{Platform: &Platform{Session: session}}
}
}

View File

@ -0,0 +1,75 @@
package account
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/handle"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/config"
"ArmedPolice/utils"
"errors"
)
type Instance struct{ *service.Session }
type InstanceHandle func(session *service.Session) *Instance
type (
InstanceLoginResponse struct {
Token string `json:"token"`
EffectTime int `json:"effect_time"`
}
)
func (c *Instance) Login(account, password, captchaKey, captchaValue, ip string) (interface{}, error) {
// 验证验证码
if pass, _ := handle.NewCaptcha().Validate(&handle.CaptchaImage{Key: captchaKey, Captcha: captchaValue}); !pass {
return nil, errors.New("验证码错误")
}
mSysUser := model.NewSysUser()
isExist, err := mSysUser.GetByAccountOrMobile(account)
if err != nil {
return nil, err
} else if !isExist {
return nil, errors.New("操作错误,该帐号信息不存在")
}
if !mSysUser.ValidatePassword(password) {
return nil, errors.New("操作错误,用户名或密码错误")
}
if mSysUser.TenantID > 0 {
mSysTenant := model.NewSysTenant()
var count int64
if err = model2.Count(mSysTenant.SysTenant, &count, model2.NewWhere("id", mSysUser.TenantID)); err != nil {
return nil, err
} else if count <= 0 {
return nil, errors.New("操作错误,当前组织下所有用户已禁止登陆")
}
}
session := service.NewSession()
session.Token = utils.JWTEncrypt(config.SettingInfo.TokenEffectTime, map[string]interface{}{
config.TokenForUID: mSysUser.UUID,
})
session.UID = mSysUser.UUID
session.TenantID = mSysUser.TenantID
session.Name = mSysUser.Name
session.Avatar = mSysUser.Avatar
session.Mobile = mSysUser.Mobile
session.IsAdmin = mSysUser.IsAdminUser()
service.Publish(config.EventForRedisHashProduce, config.RedisKeyForAccount, session.UIDToString(), session)
service.Publish(config.EventForAccountLoginProduce, session.TenantID, session.UID, ip)
return &InstanceLoginResponse{Token: session.Token, EffectTime: config.SettingInfo.TokenEffectTime}, nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{session}
}
}

View File

@ -1,60 +0,0 @@
package auth
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/model"
)
type (
// Tree 权限信息
Tree struct {
*model2.SysAuth
KindTitle string `json:"kind_title"`
Children []*Tree `json:"children"`
}
// TreeRole 角色权限信息
TreeRole struct {
*model2.SysAuth
KindTitle string `json:"kind_title"`
Checked bool `json:"checked"`
Children []*TreeRole `json:"children"`
}
// TreeChecked 角色选中状态
TreeChecked struct {
*model2.SysAuth
Checked bool `json:"checked"`
Children []*TreeChecked `json:"children"`
}
)
// tree 树状筛选
func tree(src []*model2.SysAuth, parentID uint64) []*Tree {
out := make([]*Tree, 0)
for _, v := range src {
if v.ParentID == parentID {
out = append(out, &Tree{
SysAuth: v,
KindTitle: v.KindTitle(),
Children: tree(src, v.ID),
})
}
}
return out
}
// TreeCheckedFunc 树状筛选
func TreeCheckedFunc(src []*model.SysAuthScene, parentID uint64) []*TreeChecked {
out := make([]*TreeChecked, 0)
for _, v := range src {
if v.ParentID == parentID {
out = append(out, &TreeChecked{
SysAuth: v.SysAuth,
Checked: v.SceneID > 0,
Children: TreeCheckedFunc(src, v.ID),
})
}
}
return out
}

View File

@ -1,34 +0,0 @@
package auth
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
)
type Instance struct{ *controller.Platform }
type InstanceHandle func(session *service.Session) *Instance
// List 列表信息
func (c *Instance) List() ([]*Tree, error) {
mSysAuth := model.NewSysAuth()
where := []*model2.ModelWhereOrder{
&model2.ModelWhereOrder{Order: model2.NewOrder("parent_id", model2.OrderModeToAsc)},
&model2.ModelWhereOrder{Order: model2.NewOrder("sort", model2.OrderModeToDesc)},
}
out := make([]*model2.SysAuth, 0)
if err := model2.Scan(mSysAuth, &out, where...); err != nil {
return nil, err
}
return tree(out, 0), nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,87 +0,0 @@
package auth
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/serve/logger"
"ArmedPolice/serve/orm"
"ArmedPolice/utils"
"gorm.io/gorm"
)
type Role struct{ *controller.Platform }
type RoleHandle func(session *service.Session) *Role
// List 角色权限列表
func (c *Role) List(roleID uint64) ([]*TreeChecked, error) {
mSysAuth := model.NewSysAuth()
out, err := mSysAuth.RoleAuth(c.TenantID, roleID)
if err != nil {
return nil, err
}
return TreeCheckedFunc(out, 0), nil
}
// Bind 角色权限绑定
func (c *Role) Bind(roleID uint64, authIDs []uint64) error {
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
mSysRoleAuth := model.NewSysRoleAuth()
err := model2.DeleteWhere(mSysRoleAuth.SysRoleAuth, []*model2.ModelWhere{model2.NewWhere("role_id", roleID)}, tx)
if err != nil {
return err
}
// 查询权限信息
mSysAuth := model.NewSysAuth()
auths := make([]*model2.SysAuth, 0)
if err = model2.Find(mSysAuth.SysAuth, &auths, &model2.ModelWhereOrder{Where: model2.NewWhereIn("id", authIDs)}); err != nil {
return err
}
authRequests := make([]*service.AuthRequest, 0)
roles := make([]*model2.SysRoleAuth, 0)
for _, v := range auths {
roles = append(roles, &model2.SysRoleAuth{
ModelTenant: model2.ModelTenant{TenantID: c.TenantID}, RoleID: roleID, AuthID: v.ID,
})
if v.Auth == "" {
continue
}
authRequests = append(authRequests, &service.AuthRequest{Url: v.Auth, Method: "*"})
}
if err = model2.Creates(mSysRoleAuth.SysRoleAuth, roles, tx); err != nil {
return err
}
go utils.TryCatch(func() {
permission := service.NewPermission([]string{utils.UintToString(roleID)}, authRequests...)(c.TenantKey, "")
// 删除角色权限
if _, err = permission.RemoveRolePolicy(); err != nil {
logger.ErrorF("删除角色【%d】规则信息错误%v", roleID, err)
return
}
if len(authRequests) > 0 {
if _, err = permission.AddPolicies(); err != nil {
logger.ErrorF("创建角色【%d】规则信息错误%v", roleID, err)
return
}
}
})
return nil
})
}
func NewRole() RoleHandle {
return func(session *service.Session) *Role {
return &Role{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,107 +0,0 @@
package auth
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/serve/logger"
"ArmedPolice/serve/orm"
"ArmedPolice/utils"
"errors"
"gorm.io/gorm"
)
type Tenant struct{ *controller.Platform }
type TenantHandle func(session *service.Session) *Tenant
// delete 删除所有权限
func (c *Tenant) delete(tenantID uint64, tenantKey string, tx *gorm.DB) error {
mSysRoleAuth := model.NewSysRoleAuth()
err := model2.DeleteWhere(mSysRoleAuth.SysRoleAuth, []*model2.ModelWhere{model2.NewWhere("tenant_id", tenantID)}, tx)
if err != nil {
return err
}
go utils.TryCatch(func() {
permission := service.NewPermission(nil)(tenantKey, "")
if succ, err := permission.RemoveFilteredGroupingPolicy(); err != nil {
logger.ErrorF("删除租户【%s】权限信息错误%v", tenantKey, err)
} else if !succ {
logger.ErrorF("删除租户【%s】权限信息失败", tenantKey)
}
})
return nil
}
// revoke 撤销某些权限
func (c *Tenant) revoke(tenantID uint64, tenantKey string, authIDs []uint64, tx *gorm.DB) error {
// 查询该租户下不含有的权限信息
mSysRuleAuth := model.NewSysRoleAuth()
out, err := mSysRuleAuth.Auths(model2.NewWhere("r.tenant_id", tenantID), model2.NewWhereNotIn("r_a.auth_id", authIDs))
if err != nil {
return err
}
if len(out) <= 0 {
return nil
}
roleAuthIDs := make([]uint64, 0)
roleIDs := make([]string, 0)
auths := make([]*service.AuthRequest, 0)
for _, v := range out {
roleAuthIDs = append(roleAuthIDs, v.ID)
roleIDs = append(roleIDs, utils.UintToString(v.RoleID))
auths = append(auths, &service.AuthRequest{Url: v.Auth, Method: "*"})
}
if err = model2.DeleteWhere(mSysRuleAuth.SysRoleAuth, []*model2.ModelWhere{model2.NewWhereIn("id", roleAuthIDs)}); err != nil {
return err
}
go utils.TryCatch(func() {
permission := service.NewPermission(roleIDs, auths...)(c.TenantKey, "")
// 删除角色权限
if _, err = permission.RemoveNamedGroupingPolicies(); err != nil {
logger.ErrorF("删除租户【%s】下角色权限错误%v", tenantKey, err)
return
}
})
return nil
}
// Bind 绑定权限
func (c *Tenant) Bind(tenantID uint64, authIDs []uint64) error {
mSysTenant := model.NewSysTenant()
mSysTenant.ID = tenantID
isExist, err := model2.FirstField(mSysTenant.SysTenant, []string{"id", "key"})
if err != nil {
return err
} else if !isExist {
return errors.New("租户/公司信息不存在或已被删除")
}
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
mSysTenantAuth := model.NewSysTenantAuth()
if err = model2.DeleteWhere(mSysTenantAuth.SysTenantAuth, []*model2.ModelWhere{model2.NewWhere("tenant_id", mSysTenant.ID)}, tx); err != nil {
return err
}
if len(authIDs) <= 0 {
// 删除租户下所有角色的权限
return c.delete(mSysTenant.ID, mSysTenant.Key, tx)
}
return c.revoke(mSysTenant.ID, mSysTenant.Key, authIDs, tx)
})
}
func NewTenant() TenantHandle {
return func(session *service.Session) *Tenant {
return &Tenant{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,33 +0,0 @@
package controller
import (
"ArmedPolice/app/service"
"ArmedPolice/config"
"ArmedPolice/serve/cache"
"ArmedPolice/utils"
)
// Platform
type Platform struct{ *service.Session }
// ReturnPages 分页数据
type ReturnPages struct {
List interface{} `json:"list"`
Count int64 `json:"total"`
}
type Key struct{}
// Generate 生成秘钥
func (*Key) Generate(len int) string {
key := utils.GetRandomString(len)
for {
isExist, _ := cache.Cache.SIsMember(config.RedisKeyForTenantKeys, key)
if !isExist {
_ = cache.Cache.SAdd(config.RedisKeyForTenantKeys, key)
return key
}
key = utils.GetRandomString(len)
}
}

View File

@ -0,0 +1,7 @@
package basic
// ReturnPages 分页数据
type ReturnPages struct {
Data interface{} `json:"data"`
Count int64 `json:"count"`
}

View File

@ -1,64 +0,0 @@
package controller
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/model"
"ArmedPolice/config"
"ArmedPolice/serve/orm"
"errors"
"time"
"gorm.io/gorm"
)
type Config struct{}
type ConfigHandle func() *Config
func (c *Config) Config(kind, page, pageSize int) (*ReturnPages, error) {
mSysConfig := model.NewSysConfig()
where := []*model2.ModelWhereOrder{
&model2.ModelWhereOrder{Order: model2.NewOrder("kind", model2.OrderModeToAsc)},
}
if kind > 0 {
where = append(where, &model2.ModelWhereOrder{Where: model2.NewWhere("kind", kind)})
}
out := make([]*model2.SysConfig, 0)
var count int64
if err := model2.Pages(mSysConfig.SysConfig, &out, page, pageSize, &count, where...); err != nil {
return nil, err
}
return &ReturnPages{List: out, Count: count}, nil
}
func (c *Config) Form(params map[string]interface{}) error {
if len(params) <= 0 {
return nil
}
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
mSysConfig := model.NewSysConfig()
now := time.Now()
for k, v := range params {
if _, has := config.SystemConfig[k]; !has {
return errors.New("UnKnown Config Key " + k)
}
if err := model2.UpdatesWhere(mSysConfig.SysConfig, map[string]interface{}{
"value": v, "updated_at": now,
}, []*model2.ModelWhere{model2.NewWhere("key", k)}, tx); err != nil {
return err
}
config.SystemConfig[k] = v
}
return nil
})
}
func NewConfig() ConfigHandle {
return func() *Config {
return &Config{}
}
}

View File

@ -1,57 +0,0 @@
package controller
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/tools/ip"
)
type Log struct{ *Platform }
type LogHandle func(session *service.Session) *Log
type (
// LogForLogin 登录日志
LogForLogin struct {
*model.SysUserLoginLogInfo
IPAddress string `json:"ip_address"`
}
)
// Login 登录日志
func (c *Log) Login(name string, page, pageSize int) (*ReturnPages, error) {
mSysUserLoginLogs := model.NewSysUserLoginLog()
where := make([]*model2.ModelWhere, 0)
if c.TenantID > 0 {
where = append(where, model2.NewWhere("l.tenant_id", c.TenantID))
}
if name != "" {
where = append(where, model2.NewWhereLike("u.name", name))
}
var count int64
out, err := mSysUserLoginLogs.Logs(page, pageSize, &count, where...)
if err != nil {
return nil, err
}
list := make([]*LogForLogin, 0)
for _, v := range out {
ipAddress, _ := ip.Find(v.IP)
list = append(list, &LogForLogin{
SysUserLoginLogInfo: v, IPAddress: string(ipAddress),
})
}
return &ReturnPages{List: list, Count: count}, nil
}
func NewLog() LogHandle {
return func(session *service.Session) *Log {
return &Log{Platform: &Platform{Session: session}}
}
}

View File

@ -1,87 +0,0 @@
package menu
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/model"
)
type (
Tree struct {
*model2.SysMenu
Children []*Tree `json:"children"`
}
TreeChecked struct {
*model2.SysMenuBasic
Checked bool `json:"checked"`
Children []*TreeChecked `json:"children"`
}
)
// tree 树状筛选
func tree(src []*model2.SysMenu, parentID uint64) []*Tree {
out := make([]*Tree, 0)
for _, v := range src {
if v.ParentID == parentID {
out = append(out, &Tree{
SysMenu: v,
Children: tree(src, v.ID),
})
}
}
return out
}
// TreeCheckedFunc 树状筛选
func TreeCheckedFunc(src []*model.SysMenuScene, parentID uint64) []*TreeChecked {
out := make([]*TreeChecked, 0)
for _, v := range src {
if v.ParentID == parentID {
out = append(out, &TreeChecked{
SysMenuBasic: v.SysMenuBasic,
Checked: v.SceneID > 0,
Children: TreeCheckedFunc(src, v.ID),
})
}
}
return out
}
// menuForSystem 系统管理员菜单
func menuForSystem(iModel model2.IModel, where ...*model2.ModelWhere) ([]*Tree, error) {
out, err := iModel.(*model.SysMenu).SystemMenu(where...)
if err != nil {
return nil, err
}
return tree(out, 0), nil
}
// menuForTenant 租户人员菜单
func menuForTenant(iModel model2.IModel, tenantID uint64) ([]*TreeChecked, error) {
out, err := iModel.(*model.SysMenu).TenantMenu(tenantID)
if err != nil {
return nil, err
}
return TreeCheckedFunc(out, 0), nil
}
func menuForRole(iModel model2.IModel, tenantID uint64, roleID uint64) ([]*TreeChecked, error) {
out, err := iModel.(*model.SysMenu).RoleMenu(tenantID, roleID)
if err != nil {
return nil, err
}
return TreeCheckedFunc(out, 0), nil
}
// menuForUser 当前用户菜单
func menuForUser(iModel model2.IModel, tenantID uint64, uid uint64) ([]*TreeChecked, error) {
out, err := iModel.(*model.SysMenu).UserMenu(uid)
if err != nil {
return nil, err
}
return TreeCheckedFunc(out, 0), nil
}

View File

@ -0,0 +1,28 @@
package menu
import (
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/service"
)
type Instance struct{ *service.Session }
type InstanceHandle func(session *service.Session) *Instance
func (c *Instance) List() (*basic.ReturnPages, error) {
return &basic.ReturnPages{Data: nil, Count: 0}, nil
}
func (c *Instance) Form() error {
return nil
}
func (c *Instance) Delete() error {
return nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{session}
}
}

View File

@ -1,113 +0,0 @@
package menu
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"errors"
"time"
)
// Instance 菜单管理
type Instance struct{ *controller.Platform }
type InstanceHandle func(session *service.Session) *Instance
type (
// InstanceParams 菜单参数
InstanceParams struct {
ID, ParentID uint64
Kind, Auth int
Name, Link, Component, Icon string
Sort, Status int
Remark string
}
)
// List 列表信息
func (c *Instance) List() ([]*Tree, error) {
mSysMenu := model.NewSysMenu()
auth := []model2.SysMenuAuth{model2.SysMenuAuthForOrdinary}
if c.IsAdmin {
auth = append(auth, model2.SysMenuAuthForSystem)
}
return menuForSystem(mSysMenu, model2.NewWhereIn("auth", auth))
}
// Data 数据操作
func (c *Instance) Data(params *InstanceParams) error {
if params.ID <= 0 {
return model2.Create(&model2.SysMenu{
SysMenuBasic: model2.SysMenuBasic{
ParentID: params.ParentID,
Name: params.Name,
Kind: model2.SysMenuKind(params.Kind),
Link: params.Link,
Component: params.Component,
Icon: params.Icon,
},
Auth: model2.SysMenuAuth(params.Auth),
Sort: params.Sort,
Status: model2.SysMenuStatusForNormal,
Remark: params.Remark,
})
}
out := model.NewSysMenu()
out.ID = params.ID
isExist, err := model2.FirstWhere(out.SysMenu)
if err != nil {
return err
} else if !isExist {
return errors.New("菜单信息不存在")
}
out.ParentID = params.ParentID
out.Name = params.Name
out.Kind = model2.SysMenuKind(params.Kind)
out.Link = params.Link
out.Component = params.Component
out.Icon = params.Icon
out.Auth = model2.SysMenuAuth(params.Auth)
out.Sort = params.Sort
out.Status = model2.SysMenuStatus(params.Status)
out.Remark = params.Remark
if err = model2.Save(out); err != nil {
return err
}
return nil
}
// Status 状态操作
func (c *Instance) Status(id uint64, status int) error {
mSysMenu := model.NewSysMenu()
mSysMenu.ID = id
if err := model2.Updates(mSysMenu.SysMenu, map[string]interface{}{
"status": status, "updated_at": time.Now(),
}); err != nil {
return err
}
return nil
}
// Delete 删除操作
func (c *Instance) Delete(id uint64) error {
mSysMenu := model.NewSysMenu()
mSysMenu.ID = id
if err := model2.Delete(mSysMenu.SysMenu); err != nil {
return err
}
return nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,74 +0,0 @@
package menu
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/serve/orm"
"errors"
"gorm.io/gorm"
)
type Role struct{ *controller.Platform }
type RoleHandle func(session *service.Session) *Role
// List 列表信息
func (c *Role) List(roleID uint64) ([]*TreeChecked, error) {
mSysMenu := model.NewSysMenu()
return menuForRole(mSysMenu, c.TenantID, roleID)
}
// Bind 绑定菜单
func (c *Role) Bind(roleID uint64, menuIDs []uint64) error {
if len(menuIDs) > 0 {
var count int64
mSysMenu := model.NewSysMenu()
if err := model2.Count(mSysMenu.SysMenu, &count, model2.NewWhereIn("id", menuIDs),
model2.NewWhere("auth", model2.SysMenuAuthForSystem)); err != nil {
return err
} else if count > 0 {
return errors.New("不可设置超管菜单")
}
}
mSysRoleMenu := model.NewSysRoleMenu()
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
err := model2.DeleteWhere(mSysRoleMenu.SysRoleMenu, []*model2.ModelWhere{model2.NewWhere("role_id", roleID)}, tx)
if err != nil {
return err
}
if len(menuIDs) <= 0 {
return nil
}
menus := make([]*model2.SysRoleMenu, 0)
mark := make(map[uint64]uint64, 0)
for _, v := range menuIDs {
if _, has := mark[v]; has {
continue
}
menus = append(menus, &model2.SysRoleMenu{
ModelTenant: model2.ModelTenant{TenantID: c.TenantID}, RoleID: roleID, MenuID: v,
})
mark[v] = v
}
if err = model2.Creates(mSysRoleMenu.SysRoleMenu, menus, tx); err != nil {
return err
}
return nil
})
}
func NewRole() RoleHandle {
return func(session *service.Session) *Role {
return &Role{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,91 +0,0 @@
package menu
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"ArmedPolice/serve/orm"
"errors"
"gorm.io/gorm"
)
type Tenant struct{ *controller.Platform }
type TenantHandle func(session *service.Session) *Tenant
func (c *Tenant) auth() {
}
// List 列表信息
func (c *Tenant) List(tenantID uint64) ([]*TreeChecked, error) {
mSysMenu := model.NewSysMenu()
return menuForTenant(mSysMenu, tenantID)
}
// Bind 绑定菜单
func (c *Tenant) Bind(tenantID uint64, menuIDs []uint64) error {
if len(menuIDs) > 0 {
var count int64
mSysMenu := model.NewSysMenu()
if err := model2.Count(mSysMenu.SysMenu, &count, model2.NewWhereIn("id", menuIDs),
model2.NewWhere("auth", model2.SysMenuAuthForSystem)); err != nil {
return err
} else if count > 0 {
return errors.New("不可设置超管菜单")
}
}
mSysTenantMenu := model.NewSysTenantMenu()
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
// TODO先全部删除后期考虑局部删除
err := model2.DeleteWhere(mSysTenantMenu.SysTenantMenu, []*model2.ModelWhere{model2.NewWhere("tenant_id", tenantID)}, tx)
if err != nil {
return err
}
// 租户角色的菜单
mSysRoleMenu := model.NewSysRoleMenu()
if len(menuIDs) <= 0 {
if err = model2.DeleteWhere(mSysRoleMenu.SysRoleMenu, []*model2.ModelWhere{model2.NewWhere("tenant_id", tenantID)}, tx); err != nil {
return err
}
return nil
}
menus := make([]*model2.SysTenantMenu, 0)
mark := make(map[uint64]uint64, 0)
for _, v := range menuIDs {
if _, has := mark[v]; has {
continue
}
menus = append(menus, &model2.SysTenantMenu{
ModelTenant: model2.ModelTenant{TenantID: tenantID}, MenuID: v,
})
mark[v] = v
}
if err = model2.Creates(mSysTenantMenu.SysTenantMenu, menus, tx); err != nil {
return err
}
// 删除租户下角色不存在的菜单
if err = model2.DeleteWhere(mSysRoleMenu.SysRoleMenu, []*model2.ModelWhere{
model2.NewWhere("tenant_id", tenantID),
model2.NewWhereNotIn("menu_id", menuIDs),
}); err != nil {
return err
}
return nil
})
}
func NewTenant() TenantHandle {
return func(session *service.Session) *Tenant {
return &Tenant{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,42 +0,0 @@
package menu
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
)
type User struct{ *controller.Platform }
type UserHandle func(session *service.Session) *User
// User 用户列表
func (c *User) List() (interface{}, error) {
mSysMenu := model.NewSysMenu()
if c.IsAdmin {
return menuForSystem(mSysMenu)
}
mSysUserTenant := model.NewSysUserTenant()
isExist, err := model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "identity"},
model2.NewWhere("tenant_id", c.TenantID),
model2.NewWhere("uid", c.UID))
if err != nil {
return nil, err
} else if !isExist {
return nil, nil
}
if mSysUserTenant.Identity == model2.SysUserTenantIdentityForSystemAdmin {
return menuForTenant(mSysMenu, c.TenantID)
}
return menuForUser(mSysMenu, c.TenantID, c.UID)
}
func NewUser() UserHandle {
return func(session *service.Session) *User {
return &User{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -1,173 +1,28 @@
package role
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/service"
"ArmedPolice/serve/logger"
"ArmedPolice/utils"
"errors"
"time"
)
type Instance struct{ *controller.Platform }
type Instance struct{ *service.Session }
type InstanceHandle func(session *service.Session) *Instance
type (
// InstanceInfo 角色信息
InstanceInfo struct {
*model2.SysRole
StatusTitle string `json:"status_title"`
}
// InstanceBasicInfo 角色基本信息
InstanceBasicInfo struct {
ID uint64 `json:"id"`
Name string `json:"name"`
}
)
// List 列表信息
func (c *Instance) List(name string, status, page, pageSize int) (*controller.ReturnPages, error) {
mSysRole := model.NewSysRole()
where := []*model2.ModelWhereOrder{
&model2.ModelWhereOrder{
Where: model2.NewWhere("tenant_id", c.TenantID),
Order: model2.NewOrder("sort", model2.OrderModeToDesc),
},
&model2.ModelWhereOrder{
Order: model2.NewOrder("id", model2.OrderModeToDesc),
},
}
if name != "" {
where = append(where, &model2.ModelWhereOrder{
Where: model2.NewWhere("tenant_id", c.TenantID),
})
}
if status > 0 {
where = append(where, &model2.ModelWhereOrder{
Where: model2.NewWhere("status", status),
})
}
var count int64
out := make([]*model2.SysRole, 0)
if err := model2.Pages(mSysRole.SysRole, &out, page, pageSize, &count, where...); err != nil {
return nil, err
}
list := make([]*InstanceInfo, 0)
for _, v := range out {
list = append(list, &InstanceInfo{SysRole: v, StatusTitle: v.StatusTitle()})
}
return &controller.ReturnPages{List: list, Count: count}, nil
func (c *Instance) List() (*basic.ReturnPages, error) {
return &basic.ReturnPages{Data: nil, Count: 0}, nil
}
// Select 筛选信息
func (c *Instance) Select() ([]*InstanceBasicInfo, error) {
mSysRole := model.NewSysRole()
where := []*model2.ModelWhereOrder{
&model2.ModelWhereOrder{
Where: model2.NewWhere("tenant_id", c.TenantID),
Order: model2.NewOrder("sort", model2.OrderModeToDesc),
},
&model2.ModelWhereOrder{
Where: model2.NewWhere("status", model2.SysRoleStatusForNormal),
Order: model2.NewOrder("id", model2.OrderModeToDesc),
},
}
out := make([]*InstanceBasicInfo, 0)
if err := model2.Scan(mSysRole.SysRole, &out, where...); err != nil {
return nil, err
}
return out, nil
}
// Data 数据操作
func (c *Instance) Data(id uint64, name, remark string, sort int) error {
mSysRole := model.NewSysRole()
if id <= 0 {
mSysRole.TenantID = c.TenantID
mSysRole.Name = name
mSysRole.Remark = remark
mSysRole.Sort = sort
mSysRole.Status = model2.SysRoleStatusForNormal
if err := model2.Create(mSysRole.SysRole); err != nil {
return err
}
return nil
}
mSysRole.ID = id
if err := model2.Updates(mSysRole.SysRole, map[string]interface{}{
"name": name, "remark": remark, "sort": sort,
}); err != nil {
return err
}
func (c *Instance) Form() error {
return nil
}
// Status 状态操作
func (c *Instance) Status(id uint64, status int) error {
mSysRole := model.NewSysRole()
mSysRole.ID = id
isExist, err := model2.FirstWhere(mSysRole.SysRole)
if err != nil {
return err
} else if !isExist {
return errors.New("角色不存在")
}
if c.TenantID > 0 && c.TenantID != mSysRole.TenantID {
return errors.New("不可操作其他租户角色")
}
if err = model2.Updates(mSysRole.SysRole, map[string]interface{}{
"status": status, "updated_at": time.Now(),
}); err != nil {
return err
}
return nil
}
// Delete 删除操作
func (c *Instance) Delete(id uint64) error {
mSysRole := model.NewSysRole()
mSysRole.ID = id
isExist, err := model2.FirstWhere(mSysRole.SysRole)
if err != nil {
return err
} else if !isExist {
return errors.New("角色不存在")
}
if c.TenantID > 0 && c.TenantID != mSysRole.TenantID {
return errors.New("不可删除其他租户角色")
}
if err = model2.Delete(mSysRole.SysRole); err != nil {
return err
}
go utils.TryCatch(func() {
permission := service.NewPermission([]string{utils.UintToString(id)})(c.TenantKey, "")
// 删除角色权限
if _, err = permission.RemoveRolePolicy(); err != nil {
logger.ErrorF("删除租户【%s】下角色【%d】权限信息错误%v", c.TenantKey, id, err)
return
}
})
func (c *Instance) Delete() error {
return nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{Platform: &controller.Platform{Session: session}}
return &Instance{session}
}
}

View File

@ -1,81 +0,0 @@
package role
import (
model2 "TenantServe/app/common/model"
"TenantServe/serve/logger"
"TenantServe/app/controller"
"TenantServe/app/model"
"TenantServe/app/service"
"TenantServe/serve/orm"
"TenantServe/utils"
"gorm.io/gorm"
)
type User struct{ *controller.Platform }
type UserHandle func(session *service.Session) *User
// List 列表信息
func (c *User) List(uid uint64) ([]*model.SysRoleUserInfo, error) {
mSysRole := model.NewSysRole()
out, err := mSysRole.UserRole(uid)
if err != nil {
return nil, err
}
return out, nil
}
// Bind 绑定角色
func (c *User) Bind(uid uint64, roleIDs []uint64) error {
mSysUserRole := model.NewSysUserRole()
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
err := model2.DeleteWhere(mSysUserRole.SysUserRole, []*model2.ModelWhere{model2.NewWhere("uid", uid)}, tx)
if err != nil {
return err
}
roles := make([]*model2.SysUserRole, 0)
obj := make([]string, 0)
mark := make(map[uint64]uint64, 0)
for _, v := range roleIDs {
if _, has := mark[v]; has {
continue
}
obj = append(obj, utils.UintToString(v))
roles = append(roles, &model2.SysUserRole{
UID: uid, RoleID: v,
})
mark[v] = v
}
if err = model2.Creates(mSysUserRole.SysUserRole, roles, tx); err != nil {
return err
}
go utils.TryCatch(func() {
permission := service.NewPermission(obj)(c.TenantKey, utils.UintToString(uid))
if _, err = permission.DeleteRolesForUser(false); err != nil {
logger.ErrorF("删除用户【%d】角色权限错误%v", uid, err)
return
}
if _, err = permission.AddRoleForUser(); err != nil {
logger.ErrorF("添加用户【%d】角色权限错误%v", uid, err)
return
}
})
return nil
})
}
func NewUser() UserHandle {
return func(session *service.Session) *User {
return &User{Platform: &controller.Platform{Session: session}}
}
}

View File

@ -0,0 +1,120 @@
package supplier
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"errors"
"time"
)
type Instance struct{ *service.Session }
type InstanceHandle func(session *service.Session) *Instance
type (
// InstanceInfo 基本信息
InstanceInfo struct {
ID string `json:"id"`
*model2.ManageSupplier
}
// InstanceParams 参数信息
InstanceParams struct {
ID uint64
Name, Mobile, Address, Remark string
Kind model2.ManageSupplierKind
}
)
// List 列表信息
func (c *Instance) List(name, mobile string, kind model2.ManageSupplierKind, page, pageSize int) (*basic.ReturnPages, error) {
mManageSupplier := model.NewManageSupplier()
out := make([]*model2.ManageSupplier, 0)
where := []*model2.ModelWhereOrder{&model2.ModelWhereOrder{
Where: nil,
Order: model2.NewOrder("id", model2.OrderModeToDesc),
}}
if c.TenantID > 0 {
where = append(where, &model2.ModelWhereOrder{
Where: model2.NewWhereLike("tenant_id", c.TenantID),
})
}
if name != "" {
where = append(where, &model2.ModelWhereOrder{
Where: model2.NewWhereLike("name", name),
})
}
if mobile != "" {
where = append(where, &model2.ModelWhereOrder{
Where: model2.NewWhereLike("mobile", mobile),
})
}
if kind > 0 {
where = append(where, &model2.ModelWhereOrder{
Where: model2.NewWhere("kind", kind),
})
}
var count int64
if err := model2.Pages(mManageSupplier.ManageSupplier, &out, page, pageSize, &count, where...); err != nil {
return nil, err
}
list := make([]*InstanceInfo, 0)
for _, v := range out {
list = append(list, &InstanceInfo{
ID: v.GetEncodeID(), ManageSupplier: v,
})
}
return &basic.ReturnPages{Data: list, Count: count}, nil
}
// Form 数据处理
func (c *Instance) Form(params *InstanceParams) error {
mManageSupplier := model.NewManageSupplier()
if params.ID > 0 {
mManageSupplier.ID = params.ID
isExist, err := model2.FirstWhere(mManageSupplier.ManageSupplier)
if err != nil {
return err
} else if !isExist {
return errors.New("操作错误,供应商信息不存在")
}
}
mManageSupplier.Name = params.Name
mManageSupplier.Mobile = params.Mobile
mManageSupplier.Address = params.Address
mManageSupplier.Remark = params.Remark
if mManageSupplier.ID > 0 {
mManageSupplier.UpdatedAt = time.Now()
return model2.Updates(mManageSupplier.ManageSupplier, mManageSupplier.ManageSupplier)
}
mManageSupplier.TenantID = c.TenantID
mManageSupplier.Kind = params.Kind
return model2.Create(mManageSupplier.ManageSupplier)
}
// Delete 删除操作
func (c *Instance) Delete(id uint64) error {
mManageSupplier := model.NewManageSupplier()
mManageSupplier.ID = id
if err := model2.Delete(mManageSupplier.ManageSupplier); err != nil {
return err
}
return nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{session}
}
}

View File

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

View File

@ -1,20 +0,0 @@
package tenant
// InstanceParamsForProtocol 协议参数
type InstanceParamsForSetting struct {
Protocol []uint
MaxDevices, MaxCustomer int
}
// NewProtocol 消息协议
func (c *InstanceParamsForSetting) NewProtocol() uint {
// &0&0=0 0&1=0 1&0=0 1&1=1
// |0&0=0 0&1=1 1&0=1 1&1=1
// ^0^0=0 0&1=1 1^0=1 1^1=0
var protocol uint
for i := 0; i < len(c.Protocol); i++ {
}
return protocol
}

View File

@ -1,44 +0,0 @@
package tenant
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/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.SettingInfo.Engine.Mysql.DBName))
return nil
}

View File

@ -1,249 +1,28 @@
package user
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/controller"
"ArmedPolice/app/model"
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/service"
"ArmedPolice/serve/orm"
"ArmedPolice/utils"
"errors"
"strings"
"time"
"gorm.io/gorm"
)
type Instance struct{ *controller.Platform }
type Instance struct{ *service.Session }
type InstanceHandle func(session *service.Session) *Instance
type (
// InstanceInfo 基本信息
InstanceInfo struct {
UID string `json:"uid"`
Name string `json:"name"`
Email string `json:"email"`
Mobile string `json:"mobile"`
Remark string `json:"remark"`
}
// InstanceUserInfo 用户信息
InstanceUserInfo struct {
*model.SysUserTenantUser
UID string `json:"uid"`
}
)
// InstanceForm 表单信息
type InstanceForm struct {
ID uint64 // 租户用户主键ID
Account, Name, Mobile, Password, Remark string
Gender int
Departments, Roles []uint64
func (c *Instance) List() (*basic.ReturnPages, error) {
return &basic.ReturnPages{Data: nil, Count: 0}, nil
}
// Info 用户信息
func (c *Instance) Info() (*InstanceInfo, error) {
mSysUser := model.NewSysUser()
_, err := model2.FirstWhere(mSysUser.SysUser, model2.NewWhere("uuid", c.UID))
if err != nil {
return nil, err
}
return &InstanceInfo{
UID: mSysUser.UUIDString(), Name: mSysUser.Name, Email: mSysUser.Email, Mobile: mSysUser.Mobile, Remark: mSysUser.Remark,
}, nil
}
// List 列表信息
func (c *Instance) List(name, mobile string, status, page, pageSize int) (*controller.ReturnPages, error) {
mSysUserTenant := model.NewSysUserTenant()
where := []*model2.ModelWhere{model2.NewWhere("u_t.tenant_id", c.TenantID)}
if name != "" {
where = append(where, model2.NewWhereLike("u.name", name))
}
if mobile != "" {
where = append(where, model2.NewWhereLike("u.mobile", mobile))
}
if status > 0 {
where = append(where, model2.NewWhere("u_t.status", status))
}
var count int64
out, err := mSysUserTenant.User(page, pageSize, &count, where...)
if err != nil {
return nil, err
}
list := make([]*InstanceUserInfo, 0)
for _, v := range out {
list = append(list, &InstanceUserInfo{SysUserTenantUser: v, UID: utils.UintToString(v.UID)})
}
return &controller.ReturnPages{List: list, Count: count}, nil
}
// Add 添加用户
func (c *Instance) Add(params *InstanceForm) error {
if utils.ValidateMobile(params.Mobile) {
return errors.New("手机号码格式错误")
}
mSysUser := model.NewSysUser()
// 查询登录账户或手机号码是否注册
var count int64
err := model2.Count(mSysUser.SysUser, &count, model2.NewWhere("account", params.Account))
if err != nil {
return err
}
if err = model2.Count(mSysUser.SysUser, &count, model2.NewWhere("mobile", params.Mobile)); err != nil {
return err
}
mSysUser.Account = params.Account
mSysUser.Name = params.Name
mSysUser.Mobile = params.Mobile
mSysUser.Gender.Gender = model2.GenderKind(params.Gender)
mSysUser.Password = params.Password
mSysUser.Remark = params.Remark
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
if err = model2.Create(mSysUser.SysUser, tx); err != nil {
return err
}
mSysUserTenant := model.NewSysUserTenant()
mSysUserTenant.TenantID = c.TenantID
mSysUserTenant.UID = mSysUser.UUID
if len(params.Departments) > 0 {
mSysUserTenant.Department = strings.Join(utils.ArrayStrings(params.Departments), ",")
}
if len(params.Roles) > 0 {
mSysUserTenant.Role = strings.Join(utils.ArrayStrings(params.Roles), ",")
}
mSysUserTenant.Identity = model2.SysUserTenantIdentityForSystemUser
if err = model2.Create(mSysUserTenant.SysUserTenant, tx); err != nil {
return err
}
return nil
})
}
// Edit 修改用户信息
func (c *Instance) Edit(params *InstanceForm) error {
if utils.ValidateMobile(params.Mobile) {
return errors.New("手机号码格式错误")
}
mSysUserTenant := model.NewSysUserTenant()
mSysUserTenant.ID = params.ID
isExist, err := model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"})
if err != nil {
return nil
} else if !isExist {
return errors.New("用户信息不存在")
} else if mSysUserTenant.TenantID != c.TenantID {
return errors.New("不可修改他人用户信息")
}
// 查询用户信息
mSysUser := model.NewSysUser()
if isExist, err = model2.FirstWhere(mSysUser.SysUser, model2.NewWhere("uuid", mSysUserTenant.UID)); err != nil {
return err
} else if !isExist {
return errors.New("用户信息不存在")
}
if params.Mobile != mSysUser.Mobile {
var count int64
if err = model2.Count(mSysUser.SysUser, &count, model2.NewWhere("mobile", params.Mobile)); err != nil {
return err
} else if count > 0 {
return errors.New("该手机号码已注册")
}
}
now := time.Now()
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
if err = model2.Updates(mSysUserTenant.SysUserTenant, map[string]interface{}{
"department": strings.Join(utils.ArrayStrings(params.Departments), ","),
"role": strings.Join(utils.ArrayStrings(params.Roles), ","),
"updated_at": now,
}, tx); err != nil {
return err
}
if err = model2.Updates(mSysUser.SysUser, map[string]interface{}{
"name": params.Name, "mobile": params.Mobile, "gender": params.Gender, "remark": params.Remark, "updated_at": now,
}, tx); err != nil {
return err
}
return nil
})
}
func (c *Instance) Password(id uint64, password, repeatPwd string) error {
if password != repeatPwd {
return errors.New("两次密码不一致")
}
mSysUserTenant := model.NewSysUserTenant()
mSysUserTenant.ID = id
isExist, err := model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"})
if err != nil {
return nil
} else if !isExist {
return errors.New("用户信息不存在")
} else if mSysUserTenant.TenantID != c.TenantID {
return errors.New("不可修改他人用户密码")
}
mSysUser := model.NewSysUser()
mSysUser.Password = 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
}
func (c *Instance) Form() error {
return nil
}
func (c *Instance) Delete(id uint64) error {
mSysUserTenant := model.NewSysUserTenant()
mSysUserTenant.ID = id
isExist, err := model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"})
if err != nil {
return nil
} else if !isExist {
return errors.New("用户信息不存在")
} else if mSysUserTenant.TenantID != c.TenantID {
return errors.New("不可删除他人用户信息")
}
return orm.GetDB().Transaction(func(tx *gorm.DB) error {
if err = model2.Delete(mSysUserTenant.SysUserTenant, tx); err != nil {
return err
}
mSysUser := model.NewSysUser()
if err = model2.DeleteWhere(mSysUser.SysUser, []*model2.ModelWhere{
model2.NewWhere("uuid", mSysUserTenant.UID),
}, tx); err != nil {
return err
}
return nil
})
func (c *Instance) Delete() error {
return nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{Platform: &controller.Platform{Session: session}}
return &Instance{session}
}
}

View File

@ -1,47 +0,0 @@
package user
import (
model2 "ArmedPolice/app/common/model"
"ArmedPolice/app/model"
"ArmedPolice/app/service"
"errors"
"time"
)
type Person struct{ *service.Session }
type PersonHandle func(session *service.Session) *Person
// EditPassword 修改密码
func (c *Person) EditPassword(oldPassword, password, repeatPwd string) error {
if password != repeatPwd {
return errors.New("两次密码不一致")
}
mSysUser := model.NewSysUser()
isExist, err := model2.FirstWhere(mSysUser.SysUser, model2.NewWhere("uuid", c.UID))
if err != nil {
return err
} else if !isExist {
return errors.New("用户信息不存在或已被删除")
}
if !mSysUser.ValidatePassword(oldPassword) {
return errors.New("旧密码错误")
}
mSysUser.Password = password
mSysUser.Pass()
if err = model2.Updates(mSysUser.SysUser, map[string]interface{}{
"password": mSysUser.Password, "salt": mSysUser.Salt, "updated_at": time.Now(),
}); err != nil {
return err
}
return nil
}
func NewPerson() PersonHandle {
return func(session *service.Session) *Person {
return &Person{Session: session}
}
}

View File

@ -0,0 +1,28 @@
package user
import (
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/service"
)
type Role struct{ *service.Session }
type RoleHandle func(session *service.Session) *Role
func (c *Role) List() (*basic.ReturnPages, error) {
return &basic.ReturnPages{Data: nil, Count: 0}, nil
}
func (c *Role) Form() error {
return nil
}
func (c *Role) Delete() error {
return nil
}
func NewRole() RoleHandle {
return func(session *service.Session) *Role {
return &Role{session}
}
}

View File

@ -0,0 +1,28 @@
package work
import (
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/service"
)
type Instance struct{ *service.Session }
type InstanceHandle func(session *service.Session) *Instance
func (c *Instance) List() (*basic.ReturnPages, error) {
return &basic.ReturnPages{Data: nil, Count: 0}, nil
}
func (c *Instance) Form() error {
return nil
}
func (c *Instance) Delete() error {
return nil
}
func NewInstance() InstanceHandle {
return func(session *service.Session) *Instance {
return &Instance{session}
}
}

View File

@ -1,9 +1,9 @@
package app
import (
"Edu/app/event"
"Edu/app/service"
"Edu/config"
"ArmedPolice/app/event"
"ArmedPolice/app/service"
"ArmedPolice/config"
)
func Init() {

View File

@ -0,0 +1,11 @@
package model
import "ArmedPolice/app/common/model"
type ManageSupplier struct {
*model.ManageSupplier
}
func NewManageSupplier() *ManageSupplier {
return &ManageSupplier{model.NewManageSupplier()}
}

View File

@ -1,10 +1,7 @@
package model
import (
"TenantServe/app/common/model"
"TenantServe/serve/orm"
"fmt"
"time"
"ArmedPolice/app/common/model"
)
type SysTenant struct {
@ -21,65 +18,8 @@ type (
DeviceCount int `json:"device_count"`
CustomerDeviceCount int `json:"customer_device_count"`
}
// SysTenantSubsetInfo 租户子集信息
SysTenantSubsetInfo struct {
ID uint64 `json:"id"`
ParentID uint64 `json:"parent_id"`
Name string `json:"name"`
DeviceCount int `json:"device_count"`
}
// SysTenantDeviceCount 设备数量
SysTenantDeviceCount struct {
TenantID uint64 `json:"tenant_id"`
Count int `json:"count"`
CustomerCount int `json:"customer_count"`
}
)
// IsInvalid 判断是否有效
func (m *SysTenant) IsInvalid() bool {
return m.Status == model.SysTenantStatusForDisable || m.Status == model.SysTenantStatusForExpired || m.Deadline.Before(time.Now())
}
// Tenants 租户信息
func (m *SysTenant) Tenants(page, pageSize int, count *int64, where ...*model.ModelWhere) ([]*SysTenantInfo, error) {
db := orm.GetDB().Table(m.TableName()).Where("is_deleted = ?", model.DeleteStatusForNot)
if len(where) > 0 {
for _, wo := range where {
db = db.Where(wo.Condition, wo.Value)
}
}
out := make([]*SysTenantInfo, 0)
if err := db.Count(count).Error; err != nil {
return nil, err
}
if err := db.Order("id " + model.OrderModeToDesc).Offset((page - 1) * pageSize).Limit(pageSize).Scan(&out).Error; err != nil {
return nil, err
}
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

@ -1,11 +0,0 @@
package model
import "TenantServe/app/common/model"
type SysTenantAuth struct {
*model.SysTenantAuth
}
func NewSysTenantAuth() *SysTenantAuth {
return &SysTenantAuth{SysTenantAuth: model.NewSysTenantAuth()}
}

View File

@ -1,11 +0,0 @@
package model
import "TenantServe/app/common/model"
type SysTenantMenu struct {
*model.SysTenantMenu
}
func NewSysTenantMenu() *SysTenantMenu {
return &SysTenantMenu{SysTenantMenu: model.NewSysTenantMenu()}
}

View File

@ -1,9 +1,9 @@
package model
import (
model2 "TenantServe/app/common/model"
"TenantServe/serve/orm"
"TenantServe/utils"
model2 "ArmedPolice/app/common/model"
"ArmedPolice/serve/orm"
"ArmedPolice/utils"
"errors"
"gorm.io/gorm"

View File

@ -1,83 +0,0 @@
package model
import (
"TenantServe/app/common/model"
"TenantServe/serve/orm"
"fmt"
)
type SysUserTenant struct {
*model.SysUserTenant
}
type (
// SysUserTenantBasic 基本信息
SysUserTenantBasic struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Mobile string `json:"mobile"`
Status model.SysUserTenantStatus `json:"status"`
}
// SysUserTenantUser 用户信息
SysUserTenantUser struct {
*SysUserTenantBasic
UID uint64 `json:"uid"`
Email string `json:"email"`
Identity model.SysUserTenantIdentity `json:"identity"`
Remark string `json:"remark"`
}
)
// Member 成员信息
func (m *SysUserTenant) Member(page, pageSize int, count *int64, where ...*model.ModelWhere) ([]*SysUserTenantBasic, error) {
mSysUser := NewSysUser()
db := orm.GetDB().Table(m.TableName()+" AS u_t").
Select("u_t.id, u.name, u.mobile, u_t.status").
Joins(fmt.Sprintf("LEFT JOIN %s AS u ON u_t.uid = u.uuid", mSysUser.TableName())).
Where("u_t.is_deleted = ? AND u.is_deleted = ?", model.DeleteStatusForNot, model.DeleteStatusForNot)
if len(where) > 0 {
for _, wo := range where {
db = db.Where(wo.Condition, wo.Value)
}
}
out := make([]*SysUserTenantBasic, 0)
if err := db.Count(count).Error; err != nil {
return nil, err
}
if err := db.Order("u_t.id " + model.OrderModeToDesc).Offset((page - 1) * pageSize).Limit(pageSize).Scan(&out).Error; err != nil {
return nil, err
}
return out, nil
}
// User 用户信息
func (m *SysUserTenant) User(page, pageSize int, count *int64, where ...*model.ModelWhere) ([]*SysUserTenantUser, error) {
mSysUser := NewSysUser()
db := orm.GetDB().Table(m.TableName()+" AS u_t").
Select("u_t.id, u_t.uid, u.name, u.mobile, u.email, u_t.identity, u_t.status, u.remark, u_t.created_at").
Joins(fmt.Sprintf("LEFT JOIN %s AS u ON u_t.uid = u.uuid", mSysUser.TableName())).
Where("u_t.is_deleted = ? AND u.is_deleted = ?", model.DeleteStatusForNot, model.DeleteStatusForNot)
if len(where) > 0 {
for _, wo := range where {
db = db.Where(wo.Condition, wo.Value)
}
}
out := make([]*SysUserTenantUser, 0)
if err := db.Count(count).Error; err != nil {
return nil, err
}
if err := db.Order("u_t.id " + model.OrderModeToDesc).Offset((page - 1) * pageSize).Limit(pageSize).Scan(&out).Error; err != nil {
return nil, err
}
return out, nil
}
func NewSysUserTenant() *SysUserTenant {
return &SysUserTenant{SysUserTenant: model.NewSysUserTenant()}
}

View File

@ -6,11 +6,13 @@ import (
)
type Session struct {
UID uint64 `json:"uid"` // 用户ID
Token string `json:"token"` // token
TenantID uint64 `json:"tenant_id"` // 租户ID
Name string `json:"name"` // 名称
SessionKey string `json:"session_key"` // 用户信息
Token string `json:"token"` // token
UID uint64 `json:"uid"` // 用户ID
TenantID uint64 `json:"tenant_id"` // 租户ID
Name string `json:"name"` // 名称
Avatar string `json:"avatar"` // 头像
Mobile string `json:"mobile"` // 联系方式
IsAdmin bool `json:"is_admin"` // 超管
}
func (this *Session) MarshalBinary() ([]byte, error) {

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash
set -e
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags release -ldflags "-X 'main.buildDateTime=$(date '+%Y-%m-%d %H:%M:%S')' -X 'main.gitCommitCode=$(git rev-list --full-history --all --abbrev-commit --max-count 1)' -s -w" -o Edu main.go
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags release -ldflags "-X 'main.buildDateTime=$(date '+%Y-%m-%d %H:%M:%S')' -X 'main.gitCommitCode=$(git rev-list --full-history --all --abbrev-commit --max-count 1)' -s -w" -o ArmedPolice main.go

View File

@ -0,0 +1,73 @@
package controller
import (
"ArmedPolice/utils"
"bytes"
"fmt"
"go/format"
"text/template"
)
const ControllerTemplate = `package {{.Name}}
import (
"ArmedPolice/app/controller/basic"
"ArmedPolice/app/service"
)
type {{.StrutName}} struct{ *service.Session }
type {{.StrutName}}Handle func(session *service.Session) *{{.StrutName}}
func (c *{{.StrutName}}) List() (*basic.ReturnPages, error) {
return &basic.ReturnPages{Data: nil, Count: 0}, nil
}
func (c *{{.StrutName}}) Form() error {
return nil
}
func (c *{{.StrutName}}) Delete() error {
return nil
}
func New{{.StrutName}}() {{.StrutName}}Handle {
return func(session *service.Session) *{{.StrutName}} {
return &{{.StrutName}}{session}
}
}`
type ControllerFile struct {
// Name is the plugin name. Snack style.
Name string
// StrutName is the struct name.
StrutName string
}
func (v *ControllerFile) Execute(file, tmplName, tmpl string) error {
fmt.Println(file)
f, err := utils.Open(file)
if err != nil {
return err
}
defer f.Close()
temp := new(template.Template)
if temp, err = template.New(tmplName).Parse(tmpl); err != nil {
return err
}
buf := new(bytes.Buffer)
if err = temp.Execute(buf, v); err != nil {
return err
}
out := make([]byte, 0)
if out, err = format.Source(buf.Bytes()); err != nil {
return err
}
_, err = f.Write(out)
return err
}

View File

@ -0,0 +1,75 @@
package controller
import (
"ArmedPolice/config"
"ArmedPolice/serve/logger"
"ArmedPolice/utils"
"fmt"
"os"
"path"
"strings"
"github.com/spf13/cobra"
)
var ControllerCommand = &cobra.Command{
Use: "make:controller",
Short: "quick make controller",
Example: "ctl make:controller -f sys_user -t sys_user",
Version: *config.Version,
}
var (
file string
address string
)
func init() {
ControllerCommand.Flags().StringVarP(&file, "file", "f", "", "The file name.")
ControllerCommand.Flags().StringVarP(&address, "address", "a", "", "The file controller address")
ControllerCommand.Run = func(cmd *cobra.Command, args []string) {
utils.TryCatch(func() {
if file == "" {
logger.ErrorF("Filename Not Nil")
return
}
output := "../../app/controller"
if address == "" {
logger.ErrorF("Address Not Nil")
return
}
// 解析文件地址
address = strings.Replace(address, "/", "", -1)
addresss := strings.Split(address, "/")
file := strings.ToLower(file)
dir, err := os.Getwd()
output = path.Join(dir, output+"/"+address)
if err != nil {
logger.ErrorF("Make Controller Error%v", err)
return
}
if err = utils.PrepareOutput(output); err != nil {
logger.ErrorF("Make Controller Error%v", err)
return
}
fmt.Println(output)
modelFile := &ControllerFile{
Name: addresss[len(addresss)-1],
StrutName: utils.ToSnake(file, "_"),
}
err = modelFile.Execute(path.Join(output, file+".go"), "controller", ControllerTemplate)
if err != nil {
logger.ErrorF("Make Controller Error%v", err)
return
}
return
})
}
}

View File

@ -1,9 +1,9 @@
package model
import (
"Edu/config"
"Edu/serve/logger"
"Edu/utils"
"ArmedPolice/config"
"ArmedPolice/serve/logger"
"ArmedPolice/utils"
"fmt"
"os"
"path"
@ -42,7 +42,7 @@ func init() {
dir, err := os.Getwd()
output := "/app/common/model"
output := "../..//app/common/model"
output = path.Join(dir, output)

View File

@ -1,8 +1,9 @@
package main
import (
"Edu/cmd/ctl/command/model"
"Edu/config"
"ArmedPolice/cmd/ctl/command/controller"
"ArmedPolice/cmd/ctl/command/model"
"ArmedPolice/config"
"github.com/spf13/cobra"
)
@ -14,6 +15,7 @@ var rootCmd = &cobra.Command{
}
func init() {
rootCmd.AddCommand(controller.ControllerCommand)
rootCmd.AddCommand(model.ModelCommand)
}

View File

@ -2,6 +2,7 @@ package serve
import (
"ArmedPolice/app"
"ArmedPolice/app/common"
"ArmedPolice/config"
"ArmedPolice/lib"
"ArmedPolice/router"
@ -10,7 +11,6 @@ import (
"ArmedPolice/serve/orm"
"ArmedPolice/serve/web"
"ArmedPolice/task"
"ArmedPolice/tools"
"strings"
"github.com/gin-gonic/gin"
@ -21,8 +21,7 @@ type Serve struct {
}
type Option struct {
Config string `json:"config"`
RpcConfig string `json:"rpc_config"`
Config string `json:"config"`
}
func (this *Serve) Run() {
@ -32,11 +31,14 @@ func (this *Serve) Run() {
obj.Upload.Exts = strings.Split(obj.Upload.Ext, ",")
logger.NewLogger().Init(&logger.Option{File: obj.Log.File, LeastDay: obj.Log.LeastDay, Level: obj.Log.Level, IsStdout: false}).Load()
})
cache.Init()
orm.Init()
if *config.Init {
common.Init()
}
cache.Init()
task.Init()
app.Init()
tools.Init()
// 开启web
web.NewWeb()(&web.WebConfig{
Port: config.SettingInfo.Server.Port, ReadTimeout: config.SettingInfo.Server.ReadTimeout,

View File

@ -17,9 +17,9 @@ config:
vip_price: 99
wechat:
# appid: wxc8b039943eca7a27
# appid: wxc8b039943eca7a27
appid: wx880e43c02bf7bd55
# appsecret: a96335396caa2e91d9f93c8ba88f83ae
# appsecret: a96335396caa2e91d9f93c8ba88f83ae
appsecret: 10017dff4f55f86cb2074003f38b5a23
# RATE 限流器
@ -43,12 +43,12 @@ engine:
complex: false
# MYSQL 配置
mysql:
# host: 47.96.31.6
host: 127.0.0.1
# host: 47.96.31.6
host: 192.168.0.188
port: 3306
user: appuser
password: ABCabc01
db_name: edu
password: ABCabc01!
db_name: armed_police
parameters: charset=utf8mb4,utf8&parseTime=True&loc=Asia%2FShanghai
# SQLITE 配置
sqlite:
@ -59,9 +59,9 @@ cache:
# memory | redis
type: redis
redis:
addr: "127.0.0.1:6379"
password: ABCabc01
db: 4
addr: "192.168.0.188:6379"
password: ABCabc01!
db: 5
max_active: 0
max_idle: 1000
idle_timeout: 240

View File

@ -3,7 +3,8 @@ package config
import "flag"
var (
Mode = flag.String("mode", "release", "Development Environment") // debugtestrelease
Init = flag.Bool("init", false, "Project Init Status")
Mode = flag.String("mode", "release", "Development Environment")
Version = flag.String("version", "v1.0", "IOT Version")
)

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.16
require (
github.com/antonfisher/nested-logrus-formatter v1.3.1
github.com/belief428/gorm-engine v1.0.1
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/elastic/go-elasticsearch/v7 v7.15.1
github.com/gin-gonic/gin v1.7.4

2
go.sum
View File

@ -57,6 +57,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=

4576
json/area.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
package lib
import (
"Edu/utils"
"ArmedPolice/utils"
"errors"
"fmt"
"mime/multipart"

26
main.go
View File

@ -1,5 +1,27 @@
package main
func main() {
import (
"ArmedPolice/cmd/serve"
"flag"
figure "github.com/common-nighthawk/go-figure"
"runtime"
)
}
var (
ConfigFile = flag.String("config", "./config.yaml", "config.yaml path")
)
// @title TenantServe API文档
// @version 1.0
// @description TenantServe API文档
// @host 192.168.0.153:9000
// @contact.name Henry
// @contact.url https://ipeace.org.cn
// @contact.email email@ipeace.org.cn
func main() {
flag.Parse()
runtime.GOMAXPROCS(runtime.NumCPU())
figure.NewFigure("Armed Police Serve", "", true).Print()
serve.NewServe()(&serve.Option{Config: *ConfigFile}).Run()
}

View File

@ -1,10 +1,10 @@
package router
import (
"Edu/app/service"
"Edu/config"
cache2 "Edu/serve/cache"
"Edu/utils"
"ArmedPolice/app/service"
"ArmedPolice/config"
cache2 "ArmedPolice/serve/cache"
"ArmedPolice/utils"
"fmt"
"net/http"
"time"

View File

@ -1,8 +1,8 @@
package router
import (
"Edu/config"
"Edu/serve/logger"
"ArmedPolice/config"
"ArmedPolice/serve/logger"
"context"
"fmt"
"net/http"

View File

@ -1,9 +1,9 @@
package router
import (
"Edu/app/api"
"Edu/config"
"Edu/router/rate"
"ArmedPolice/app/api"
"ArmedPolice/config"
"ArmedPolice/router/rate"
"io"
"net/http"
"os"
@ -37,8 +37,8 @@ func (this *Router) registerAPI() {
g.Use()
// 登录验证
g.Use(NeedLogin(AddSkipperURL([]string{
apiPrefix + "/v1/account/authorize",
apiPrefix + "/v1/account/tourist",
apiPrefix + "/v1/account/login",
apiPrefix + "/v1/account/logout",
apiPrefix + "/v1/index",
apiPrefix + "/v1/grade",
apiPrefix + "/v1/book/list",
@ -53,39 +53,13 @@ func (this *Router) registerAPI() {
account := v1.Group("/account")
{
_api := new(api.Account)
account.POST("/authorize", _api.Authorize)
account.POST("/login", _api.Login)
account.POST("/logout", _api.Logout)
if config.IsDebug() {
account.GET("/tourist", _api.Tourist)
//account.GET("/tourist", _api.Tourist)
}
}
// Banner 接口管理
v1.GET("/index", new(api.Index).Index)
v1.GET("/grade", new(api.Index).Grade)
v1.GET("/banner", new(api.Banner).List)
v1.GET("/book/list", new(api.Book).List)
// User 接口管理
user := v1.Group("/user")
{
_api := new(api.User)
user.GET("/info", _api.Info)
}
// Book 接口管理
book := v1.Group("/book")
{
_api := new(api.Book)
book.GET("/home", _api.Home)
//book.GET("/list", _api.List)
book.GET("/detail", _api.Detail)
book.POST("/play", _api.Play)
}
// Pay 支付管理
pay := v1.Group("/pay")
{
_api := new(api.Pay)
pay.POST("/launch", _api.Launch)
pay.POST("/notice", _api.Notify)
}
}
func (this *Router) Init() *gin.Engine {

View File

@ -1,7 +1,7 @@
package logic
import (
"Edu/utils"
"ArmedPolice/utils"
"strings"
"sync"
)

View File

@ -1,7 +1,7 @@
package logger
import (
"Edu/utils"
"ArmedPolice/utils"
"fmt"
"os"
"path/filepath"

View File

@ -1,8 +1,8 @@
package orm
import (
"Edu/config"
"Edu/serve/orm/logic"
"ArmedPolice/config"
"ArmedPolice/serve/orm/logic"
"fmt"
"log"
"os"

View File

@ -1,10 +1,10 @@
package task
import (
"Edu/config"
"Edu/serve/cache"
"Edu/serve/cache/logic"
"Edu/utils"
"ArmedPolice/config"
"ArmedPolice/serve/cache"
"ArmedPolice/serve/cache/logic"
"ArmedPolice/utils"
"fmt"
"sync"
)

View File

@ -1,7 +1,7 @@
package task
import (
"Edu/utils"
"ArmedPolice/utils"
"encoding/json"
)

View File

@ -1,10 +1,10 @@
package task
import (
"Edu/config"
cache2 "Edu/serve/cache"
"Edu/serve/cache/logic"
"Edu/utils"
"ArmedPolice/config"
cache2 "ArmedPolice/serve/cache"
"ArmedPolice/serve/cache/logic"
"ArmedPolice/utils"
"fmt"
"time"
)

View File

@ -1,7 +1,7 @@
package task
import (
"Edu/utils"
"ArmedPolice/utils"
"encoding/json"
"fmt"
"time"

View File

@ -1,13 +0,0 @@
package tools
import (
"ArmedPolice/tools/ip"
)
func initIP() {
_ = ip.Load("./file/ip_chunzhen.txt")
}
func Init() {
initIP()
}

View File

@ -1,102 +0,0 @@
package ip
import (
"bufio"
"bytes"
"encoding/binary"
"io"
"net"
"strconv"
"strings"
)
type IpData []*IpRange
func NewIpData() *IpData {
return &IpData{}
}
//TODO 初始化后对数据做排序
func (id *IpData) Load(r io.Reader) error {
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
item := strings.SplitN(line, "\t", ipRangeFieldCount)
if len(item) != ipRangeFieldCount {
continue
}
begin, _ := strconv.Atoi(item[0])
end, _ := strconv.Atoi(item[1])
if begin > end {
continue
}
ir := &IpRange{
Begin: uint32(begin),
End: uint32(end),
Data: []byte(item[2]),
}
*id = append(*id, ir)
}
return scanner.Err()
}
func (id *IpData) ReLoad(r io.Reader) error {
nId := NewIpData()
err := nId.Load(r)
if err != nil {
return err
}
*id = *nId
return nil
}
func (id *IpData) Length() int {
return len(*id)
}
func (id *IpData) Find(ip string) (*IpRange, error) {
ir, err := id.getIpRange(ip)
if err != nil {
return nil, err
}
return ir, nil
}
func (id *IpData) getIpRange(ip string) (*IpRange, error) {
var low, high int = 0, (id.Length() - 1)
ipdt := *id
il := ip2Long(ip)
if il <= 0 {
return nil, ErrorIpRangeNotFound
}
for low <= high {
var middle int = (high-low)/2 + low
ir := ipdt[middle]
if il >= ir.Begin && il <= ir.End {
return ir, nil
} else if il < ir.Begin {
high = middle - 1
} else {
low = middle + 1
}
}
return nil, ErrorIpRangeNotFound
}
func ip2Long(ip string) uint32 {
var long uint32
binary.Read(bytes.NewBuffer(net.ParseIP(ip).To4()), binary.BigEndian, &long)
return long
}

View File

@ -1,17 +0,0 @@
package ip
import (
"errors"
)
const (
ipRangeFieldCount = 3
)
var ErrorIpRangeNotFound = errors.New("ip range not found")
type IpRange struct {
Begin uint32
End uint32
Data []byte
}

View File

@ -1,41 +0,0 @@
package ip
import (
"os"
)
var defaultIpData *IpData
func init() {
defaultIpData = NewIpData()
}
func Load(df string) error {
reader, err := os.Open(df)
if err != nil {
return err
}
return defaultIpData.Load(reader)
}
func ReLoad(df string) error {
reader, err := os.Open(df)
if err != nil {
return err
}
return defaultIpData.ReLoad(reader)
}
func Length() int {
return defaultIpData.Length()
}
func Find(ip string) ([]byte, error) {
ir, err := defaultIpData.Find(ip)
if err != nil {
return nil, err
} else {
return ir.Data, nil
}
}