feat:完善项目
This commit is contained in:
82
app/api/account.go
Normal file
82
app/api/account.go
Normal file
@ -0,0 +1,82 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ArmedPolice/app/controller"
|
||||
"ArmedPolice/app/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Account struct{}
|
||||
|
||||
/**
|
||||
* @apiDefine Account 账号管理
|
||||
*/
|
||||
|
||||
/**
|
||||
* @api {post} /api/account/login 账号登录
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName AccountLogin
|
||||
* @apiGroup Account
|
||||
*
|
||||
* @apiHeader {string} x-equipment 设备平台(Web,H5,App)
|
||||
*
|
||||
* @apiParam {String} account 登录账号
|
||||
* @apiParam {String} password 登录密码
|
||||
* @apiParam {Json} captcha 验证码信息
|
||||
* @apiParam {String} captcha.key 验证key
|
||||
* @apiParam {String} captcha.value 验证value
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
* @apiSuccess (200) {String} data token
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNjE3NDU2OTMwIiwiaWF0IjoiMTYxNjg1MjEzMCIsInVpZCI6IjIwMTMxMTI4MTMwMTg0MTkyMDAifQ.D7oSD4OGdz8rJt0rFNVEl5Ea47_vtuC51IDrY9mUTPo"
|
||||
* }
|
||||
*/
|
||||
func (a *Account) Login(c *gin.Context) {
|
||||
form := &struct {
|
||||
Account string `json:"account" form:"account" binding:"required"`
|
||||
Password string `json:"password" form:"password" binding:"required"`
|
||||
Captcha struct {
|
||||
Key string `json:"key" form:"key" binding:"required"`
|
||||
Value string `json:"value" form:"value" binding:"required"`
|
||||
} `json:"captcha" form:"captcha" binding:"required"`
|
||||
}{}
|
||||
if err := bind(form)(c); err != nil {
|
||||
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())
|
||||
APIResponse(err, data)(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} /api/account/logout 账号退出
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName AccountLogout
|
||||
* @apiGroup Account
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data": null
|
||||
* }
|
||||
*/
|
||||
func (a *Account) Logout(c *gin.Context) {
|
||||
err := controller.NewAccount()(getSession()(c).(*service.Session)).Logout()
|
||||
APIResponse(err)(c)
|
||||
}
|
101
app/api/auth.go
Normal file
101
app/api/auth.go
Normal file
@ -0,0 +1,101 @@
|
||||
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)
|
||||
}
|
108
app/api/base.go
Normal file
108
app/api/base.go
Normal file
@ -0,0 +1,108 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ArmedPolice/config"
|
||||
"ArmedPolice/serve/logger"
|
||||
"ArmedPolice/utils"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const (
|
||||
SuccessCode = 200 //成功的状态码
|
||||
FailureCode = 999 //失败的状态码
|
||||
)
|
||||
|
||||
type response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type ApiHandle func(c *gin.Context, syslog ...bool) interface{}
|
||||
|
||||
func (c ApiHandle) SysLog() {
|
||||
fmt.Println(123)
|
||||
//service.Publish(config.EventForSysLogProduce, _session.Community, _session.UID, _session.Name, mode, event, content,
|
||||
// c.Get("params"), c.ClientIP())
|
||||
}
|
||||
|
||||
func getSession() ApiHandle {
|
||||
return func(c *gin.Context, log ...bool) interface{} {
|
||||
value, _ := c.Get(config.TokenForSession)
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
func bind(req interface{}) ApiHandle {
|
||||
return func(c *gin.Context, log ...bool) interface{} {
|
||||
var err error
|
||||
|
||||
if c.Request.Method == "GET" {
|
||||
err = c.ShouldBindQuery(req)
|
||||
} else {
|
||||
err = c.ShouldBindBodyWith(req, binding.JSON)
|
||||
}
|
||||
if err != nil {
|
||||
logger.ErrorF("Request URL【%s】Params Bind Error:%v", c.Request.URL, err)
|
||||
return errors.New("参数异常/缺失")
|
||||
}
|
||||
c.Set("params", utils.AnyToJSON(req))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func APISuccess(data ...interface{}) ApiHandle {
|
||||
return func(c *gin.Context, log ...bool) interface{} {
|
||||
resp := &response{
|
||||
Code: SuccessCode,
|
||||
Message: "ok",
|
||||
}
|
||||
if len(data) > 0 {
|
||||
resp.Data = data[0]
|
||||
}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func APIFailure(err error) ApiHandle {
|
||||
return func(c *gin.Context, log ...bool) interface{} {
|
||||
resp := &response{
|
||||
Code: FailureCode,
|
||||
Message: "failure",
|
||||
}
|
||||
if err != nil {
|
||||
resp.Message = err.Error()
|
||||
}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
c.Abort()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func APIResponse(err error, data ...interface{}) ApiHandle {
|
||||
return func(c *gin.Context, log ...bool) interface{} {
|
||||
resp := &response{
|
||||
Code: SuccessCode,
|
||||
Message: "ok",
|
||||
}
|
||||
if err != nil {
|
||||
resp.Code = FailureCode
|
||||
resp.Message = err.Error()
|
||||
c.JSON(http.StatusOK, resp)
|
||||
c.Abort()
|
||||
return nil
|
||||
}
|
||||
if len(data) > 0 {
|
||||
resp.Data = data[0]
|
||||
}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
return nil
|
||||
}
|
||||
}
|
42
app/api/captcha.go
Normal file
42
app/api/captcha.go
Normal file
File diff suppressed because one or more lines are too long
34
app/api/config.go
Normal file
34
app/api/config.go
Normal file
@ -0,0 +1,34 @@
|
||||
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)
|
||||
}
|
23
app/api/logs.go
Normal file
23
app/api/logs.go
Normal file
@ -0,0 +1,23 @@
|
||||
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)
|
||||
}
|
425
app/api/menu.go
Normal file
425
app/api/menu.go
Normal file
@ -0,0 +1,425 @@
|
||||
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)
|
||||
}
|
107
app/api/role.go
Normal file
107
app/api/role.go
Normal file
@ -0,0 +1,107 @@
|
||||
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)
|
||||
}
|
37
app/api/struct.go
Normal file
37
app/api/struct.go
Normal file
@ -0,0 +1,37 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ArmedPolice/config"
|
||||
"ArmedPolice/utils"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type idForm struct {
|
||||
ID uint64 `json:"id" form:"id" binding:"required"`
|
||||
}
|
||||
|
||||
type uidForm struct {
|
||||
UID string `json:"uid" form:"uid" binding:"required"`
|
||||
}
|
||||
|
||||
func (this *uidForm) Convert() uint64 {
|
||||
return utils.StringToUnit64(this.UID)
|
||||
}
|
||||
|
||||
type imageForm struct {
|
||||
Image string `json:"image" form:"image"`
|
||||
}
|
||||
|
||||
func (this *imageForm) FilterImageURL() string {
|
||||
return strings.Replace(this.Image, config.SettingInfo.Domain, "", -1)
|
||||
}
|
||||
|
||||
type positionForm struct {
|
||||
Longitude float64 `json:"longitude" form:"longitude" binding:"required"`
|
||||
Latitude float64 `json:"latitude" form:"latitude" binding:"required"`
|
||||
}
|
||||
|
||||
type pageForm struct {
|
||||
Page int `json:"current" form:"current" binding:"required"`
|
||||
PageSize int `json:"pageSize" form:"pageSize" binding:"required"`
|
||||
}
|
403
app/api/tenant.go
Normal file
403
app/api/tenant.go
Normal file
@ -0,0 +1,403 @@
|
||||
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)
|
||||
}
|
64
app/api/upload.go
Normal file
64
app/api/upload.go
Normal file
@ -0,0 +1,64 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"ArmedPolice/config"
|
||||
"ArmedPolice/lib"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Upload struct{}
|
||||
|
||||
/**
|
||||
* @apiDefine Upload 上传管理
|
||||
*/
|
||||
|
||||
/**
|
||||
* @api {post} /api/upload 上传接口
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName Upload
|
||||
* @apiGroup Upload
|
||||
*
|
||||
* @apiHeader {string} x-token token
|
||||
*
|
||||
* @apiParam {File} file 文件信息
|
||||
*
|
||||
* @apiSuccess (200) {Number} code 成功响应状态码!
|
||||
* @apiSuccess (200) {String} msg 成功提示
|
||||
* @apiSuccess (200) {Object} data 具体信息
|
||||
* @apiSuccess (200) {Number} data.url 文件访问地址
|
||||
* @apiSuccess (200) {String} data.filepath 文件地址
|
||||
* @apiSuccess (200) {String} data.filename 文件名称
|
||||
*
|
||||
* @apiSuccessExample {json} Success response:
|
||||
* HTTPS 200 OK
|
||||
* {
|
||||
* "code": 200
|
||||
* "msg": "ok"
|
||||
* "data":{
|
||||
* "url": "http://192.168.99.185:8010/upload/20210401/ad228811386cb8cd089a9d668d2885cd.png",
|
||||
* "filepath": "/upload/20210401/ad228811386cb8cd089a9d668d2885cd.png",
|
||||
* "filename": "8251863448d7ed13393bf0aae2211272.jpg"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
func (a *Upload) Upload(c *gin.Context) {
|
||||
file, err := c.FormFile("file")
|
||||
|
||||
if err != nil {
|
||||
APIFailure(err)(c)
|
||||
return
|
||||
}
|
||||
resp := new(lib.UploadHandle)
|
||||
|
||||
if resp, err = lib.Upload(config.SettingInfo.Upload.Path, config.SettingInfo.Upload.Exts, config.SettingInfo.Upload.Size,
|
||||
config.SettingInfo.Upload.Rename).Handle()(file, config.SettingInfo.Domain); err != nil {
|
||||
APIFailure(err)(c)
|
||||
return
|
||||
}
|
||||
if err = c.SaveUploadedFile(file, resp.RelativePath); err != nil {
|
||||
APIFailure(err)(c)
|
||||
return
|
||||
}
|
||||
APISuccess(resp)(c)
|
||||
}
|
115
app/api/user.go
Normal file
115
app/api/user.go
Normal file
@ -0,0 +1,115 @@
|
||||
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)
|
||||
}
|
84
app/common/init.go
Normal file
84
app/common/init.go
Normal file
@ -0,0 +1,84 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"ArmedPolice/app/common/model"
|
||||
"ArmedPolice/config"
|
||||
"ArmedPolice/serve/orm"
|
||||
)
|
||||
|
||||
type synchronized struct {
|
||||
iModel model.IModel
|
||||
iValues func() interface{}
|
||||
Catch func() interface{}
|
||||
}
|
||||
|
||||
type caches struct {
|
||||
iModel model.IModel
|
||||
iValues func() interface{}
|
||||
toCache func(values interface{})
|
||||
}
|
||||
|
||||
func initModel() {
|
||||
db := orm.GetDB()
|
||||
|
||||
function := func(synchronized ...*synchronized) {
|
||||
for _, v := range synchronized {
|
||||
if !db.Migrator().HasTable(v.iModel) {
|
||||
_ = db.Migrator().CreateTable(v.iModel)
|
||||
|
||||
if v.iValues != nil && v.iValues() != nil {
|
||||
db.Table(v.iModel.TableName()).Create(v.iValues())
|
||||
}
|
||||
} else if v.Catch != nil && v.Catch() != nil {
|
||||
v.Catch()
|
||||
}
|
||||
}
|
||||
}
|
||||
function(
|
||||
&synchronized{iModel: model.NewSysTenant()}, &synchronized{iModel: model.NewSysTenantMenu()},
|
||||
&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",
|
||||
IsAdmin: model.SysUserAdministratorForAdmin, Remark: "超级管理员"}
|
||||
}},
|
||||
&synchronized{iModel: model.NewSysUserTenant()},
|
||||
&synchronized{iModel: model.NewSysDepartment()},
|
||||
&synchronized{iModel: model.NewSysRole()}, &synchronized{iModel: model.NewSysRoleMenu()}, &synchronized{iModel: model.NewSysRoleAuth()},
|
||||
&synchronized{iModel: model.NewSysUserRole()},
|
||||
// 日志管理
|
||||
&synchronized{iModel: model.NewSysLog()}, &synchronized{iModel: model.NewSysUserLoginLog()},
|
||||
)
|
||||
}
|
||||
func initCacheMode() {
|
||||
db := orm.GetDB()
|
||||
|
||||
function := func(cache ...*caches) {
|
||||
for _, v := range cache {
|
||||
if db.Migrator().HasTable(v.iModel) {
|
||||
if v.iValues != nil {
|
||||
if values := v.iValues(); values != nil {
|
||||
v.toCache(values)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function(
|
||||
&caches{iModel: model.NewSysTenant(), iValues: func() interface{} {
|
||||
out := make([]*model.SysConfig, 0)
|
||||
_ = model.Find(model.NewSysConfig(), &out)
|
||||
return out
|
||||
}, toCache: func(values interface{}) {
|
||||
out := values.([]*model.SysConfig)
|
||||
for _, v := range out {
|
||||
config.SystemConfig[v.Key] = v.Value
|
||||
}
|
||||
}},
|
||||
)
|
||||
}
|
||||
|
||||
func Init() {
|
||||
initModel()
|
||||
initCacheMode()
|
||||
}
|
74
app/common/model/common.go
Normal file
74
app/common/model/common.go
Normal file
@ -0,0 +1,74 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"ArmedPolice/utils"
|
||||
)
|
||||
|
||||
type Gender struct {
|
||||
Gender GenderKind `gorm:"column:gender;type:tinyint(1);default:1;comment:性别(1:男,2:女)" json:"gender"` // 性别(1:男,2:女)
|
||||
}
|
||||
|
||||
type GenderKind int
|
||||
|
||||
const (
|
||||
// GenderKindForMale 男性
|
||||
GenderKindForMale GenderKind = iota + 1
|
||||
// GenderKindForFemale 女性
|
||||
GenderKindForFemale
|
||||
)
|
||||
|
||||
func (m *Gender) GenderTitle() string {
|
||||
if m.Gender == GenderKindForMale {
|
||||
return "男"
|
||||
} else if m.Gender == GenderKindForFemale {
|
||||
return "女"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Image 单一图片信息
|
||||
type Image struct {
|
||||
Image string `gorm:"column:image;type:varchar(255);default:null;comment:图片" json:"image"`
|
||||
}
|
||||
|
||||
func (m *Image) Analysis(domain string) string {
|
||||
return domain + m.Image
|
||||
}
|
||||
|
||||
// Images 多个图片信息
|
||||
type Images struct {
|
||||
Images string `gorm:"column:images;type:text;default:null;comment:图片" json:"images"`
|
||||
}
|
||||
|
||||
// AnalysisSlice Slice解析
|
||||
func (m *Images) AnalysisSlice(domain string) []string {
|
||||
images := make([]string, 0)
|
||||
utils.FromJSON(m.Images, &images)
|
||||
|
||||
for k, v := range images {
|
||||
images[k] = domain + v
|
||||
}
|
||||
return images
|
||||
}
|
||||
|
||||
// Position 坐标信息
|
||||
type Position struct {
|
||||
Longitude float64 `json:"longitude"` // 经度
|
||||
Latitude float64 `json:"latitude"` // 纬度
|
||||
}
|
||||
|
||||
// Format 格式化
|
||||
func (m *Position) Format() string {
|
||||
return utils.AnyToJSON(m)
|
||||
}
|
||||
|
||||
// Tags 标签
|
||||
type Tags struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Format 格式化
|
||||
func (m *Tags) Format() string {
|
||||
return utils.AnyToJSON(m)
|
||||
}
|
421
app/common/model/model.go
Normal file
421
app/common/model/model.go
Normal file
@ -0,0 +1,421 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"ArmedPolice/serve/orm"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// IModel
|
||||
type IModel interface {
|
||||
GetID() uint64
|
||||
TableName() string
|
||||
SetDatabase(database string, key ...string)
|
||||
}
|
||||
|
||||
// Model
|
||||
type Model struct {
|
||||
ID uint64 `gorm:"column:id;primaryKey;autoIncrement;comment:主键" json:"id" form:"id"`
|
||||
|
||||
Database string `json:"-" gorm:"-"`
|
||||
}
|
||||
|
||||
// ModelTenant
|
||||
type ModelTenant struct {
|
||||
TenantID uint64 `gorm:"column:tenant_id;index:idx_sys_tenant_id;type:int(11);default:0;comment:租户ID" json:"-"`
|
||||
}
|
||||
|
||||
// ModelDeleted
|
||||
type ModelDeleted struct {
|
||||
IsDeleted DeleteStatus `gorm:"column:is_deleted;type:tinyint(1);default:0;comment:删除状态(0:未删除,1:已删除)" json:"-" form:"is_deleted"`
|
||||
}
|
||||
|
||||
// ModelAt
|
||||
type ModelAt struct {
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:datetime;not null;comment:创建时间" json:"created_at" form:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:datetime;not null;comment:更新时间" json:"updated_at" form:"updated_at"`
|
||||
}
|
||||
|
||||
// DeleteStatus 删除状态
|
||||
type DeleteStatus int
|
||||
|
||||
const (
|
||||
// DeleteStatusForNot 未删除
|
||||
DeleteStatusForNot DeleteStatus = iota
|
||||
// DeleteStatusForAlready 已删除
|
||||
DeleteStatusForAlready
|
||||
)
|
||||
|
||||
const (
|
||||
// FieldsForID 主键ID
|
||||
FieldsForID string = "id"
|
||||
// FieldsForUpdatedAt 更新时间
|
||||
FieldsForUpdatedAt string = "updated_at"
|
||||
// FieldsForDeleted 删除字段名
|
||||
FieldsForDeleted string = "is_deleted"
|
||||
)
|
||||
|
||||
const (
|
||||
SubDatabase string = "tenant"
|
||||
)
|
||||
|
||||
func (m *Model) GetID() uint64 {
|
||||
return m.ID
|
||||
}
|
||||
|
||||
func (m *Model) SetDatabase(database string, key ...string) {
|
||||
m.Database = database + "_" + strings.Join(key, "_")
|
||||
}
|
||||
|
||||
func (m *Model) NewTableName(tableName string) string {
|
||||
if m.Database == "" {
|
||||
return tableName
|
||||
}
|
||||
return m.Database + "." + tableName
|
||||
}
|
||||
|
||||
func (m *ModelAt) BeforeCreate(db *gorm.DB) error {
|
||||
m.CreatedAt = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ModelAt) BeforeUpdate(db *gorm.DB) error {
|
||||
m.UpdatedAt = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ModelDeleted) IsDelete() bool {
|
||||
return m.IsDeleted == DeleteStatusForAlready
|
||||
}
|
||||
|
||||
func Create(model IModel, session ...*gorm.DB) error {
|
||||
if len(session) > 0 {
|
||||
return session[0].Table(model.TableName()).Create(model).Error
|
||||
}
|
||||
return orm.GetDB().Table(model.TableName()).Create(model).Error
|
||||
}
|
||||
|
||||
func Creates(model IModel, objs interface{}, session ...*gorm.DB) error {
|
||||
if len(session) > 0 {
|
||||
return session[0].Table(model.TableName()).Create(objs).Error
|
||||
}
|
||||
return orm.GetDB().Table(model.TableName()).Create(objs).Error
|
||||
}
|
||||
|
||||
func Save(model IModel, session ...*gorm.DB) error {
|
||||
if len(session) > 0 {
|
||||
return session[0].Table(model.TableName()).Save(model).Error
|
||||
}
|
||||
return orm.GetDB().Table(model.TableName()).Save(model).Error
|
||||
}
|
||||
|
||||
func Updates(model IModel, value interface{}, session ...*gorm.DB) error {
|
||||
if len(session) > 0 {
|
||||
return session[0].Table(model.TableName()).Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())).Updates(value).Error
|
||||
}
|
||||
return orm.GetDB().Table(model.TableName()).Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID())).Updates(value).Error
|
||||
}
|
||||
|
||||
func UpdatesWhere(model IModel, value interface{}, where []*ModelWhere, session ...*gorm.DB) error {
|
||||
db := orm.GetDB()
|
||||
|
||||
if len(session) > 0 {
|
||||
db = session[0]
|
||||
}
|
||||
db = db.Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
return db.Updates(value).Error
|
||||
}
|
||||
|
||||
func Delete(model IModel, session ...*gorm.DB) error {
|
||||
db := orm.GetDB()
|
||||
|
||||
if len(session) > 0 {
|
||||
db = session[0]
|
||||
}
|
||||
db = db.Table(model.TableName()).Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID()))
|
||||
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
return db.Updates(map[string]interface{}{FieldsForDeleted: DeleteStatusForAlready, FieldsForUpdatedAt: time.Now()}).Error
|
||||
}
|
||||
return db.Delete(model).Error
|
||||
}
|
||||
|
||||
func DeleteWhere(model IModel, where []*ModelWhere, session ...*gorm.DB) error {
|
||||
db := orm.GetDB()
|
||||
|
||||
if len(session) > 0 {
|
||||
db = session[0]
|
||||
}
|
||||
db = db.Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
return db.Updates(map[string]interface{}{FieldsForDeleted: DeleteStatusForAlready, FieldsForUpdatedAt: time.Now()}).Error
|
||||
}
|
||||
return db.Delete(model).Error
|
||||
}
|
||||
|
||||
func Count(model IModel, count *int64, where ...*ModelWhere) error {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
return db.Count(count).Error
|
||||
}
|
||||
|
||||
func First(model IModel) (bool, error) {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.First(model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func FirstWhere(model IModel, where ...*ModelWhere) (bool, error) {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
} else {
|
||||
db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID()))
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.First(model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func FirstField(model IModel, field []string, where ...*ModelWhere) (bool, error) {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
} else {
|
||||
db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID()))
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.Select(field).First(model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func Last(model IModel) (bool, error) {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.Order("id " + OrderModeToDesc).First(model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func LastWhere(model IModel, where ...*ModelWhere) (bool, error) {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
} else {
|
||||
db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID()))
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.Order("id " + OrderModeToDesc).First(model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func LastWhereOrder(model IModel, where ...*ModelWhereOrder) (bool, error) {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
if wo.Where != nil {
|
||||
db = db.Where(wo.Where.Condition, wo.Where.Value)
|
||||
}
|
||||
if wo.Order != nil {
|
||||
db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
db = db.Where(fmt.Sprintf("%s = %d", FieldsForID, model.GetID()))
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.Limit(1).First(model).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func Find(model IModel, out interface{}, where ...*ModelWhereOrder) error {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
if wo.Where != nil {
|
||||
db = db.Where(wo.Where.Condition, wo.Where.Value)
|
||||
}
|
||||
if wo.Order != nil {
|
||||
db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
return db.Find(out).Error
|
||||
}
|
||||
|
||||
func Scan(model IModel, out interface{}, where ...*ModelWhereOrder) error {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
if wo.Where != nil {
|
||||
db = db.Where(wo.Where.Condition, wo.Where.Value)
|
||||
}
|
||||
if wo.Order != nil {
|
||||
db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
return db.Scan(out).Error
|
||||
}
|
||||
|
||||
func ScanFields(model IModel, out interface{}, fields []string, where ...*ModelWhereOrder) error {
|
||||
db := orm.GetDB().Table(model.TableName()).Select(fields)
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
if wo.Where != nil {
|
||||
db = db.Where(wo.Where.Condition, wo.Where.Value)
|
||||
}
|
||||
if wo.Order != nil {
|
||||
db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
return db.Scan(out).Error
|
||||
}
|
||||
|
||||
func Pluck(model IModel, field string, out interface{}, where ...*ModelWhere) error {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
return db.Pluck(field, out).Error
|
||||
}
|
||||
|
||||
func Pages(model IModel, out interface{}, page, pageSize int, count *int64, where ...*ModelWhereOrder) error {
|
||||
db := orm.GetDB().Table(model.TableName())
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
if wo.Where != nil {
|
||||
db = db.Where(wo.Where.Condition, wo.Where.Value)
|
||||
}
|
||||
if wo.Order != nil {
|
||||
db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.Count(count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Offset((page - 1) * pageSize).Limit(pageSize).Scan(out).Error
|
||||
}
|
||||
|
||||
func PagesFields(model IModel, out interface{}, fields []string, page, pageSize int, count *int64, where ...*ModelWhereOrder) error {
|
||||
db := orm.GetDB().Table(model.TableName()).Select(fields)
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
if wo.Where != nil {
|
||||
db = db.Where(wo.Where.Condition, wo.Where.Value)
|
||||
}
|
||||
if wo.Order != nil {
|
||||
db = db.Order(fmt.Sprintf("%s %s", wo.Order.Field, wo.Order.Mode))
|
||||
}
|
||||
}
|
||||
}
|
||||
if db.Migrator().HasColumn(model, FieldsForDeleted) {
|
||||
db = db.Where(FieldsForDeleted, DeleteStatusForNot)
|
||||
}
|
||||
if err := db.Count(count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return db.Offset((page - 1) * pageSize).Limit(pageSize).Scan(out).Error
|
||||
}
|
32
app/common/model/model_test.go
Normal file
32
app/common/model/model_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
GormEngine "github.com/belief428/gorm-engine"
|
||||
"github.com/belief428/gorm-engine/engine"
|
||||
"github.com/belief428/gorm-engine/logic"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
_db *gorm.DB
|
||||
)
|
||||
|
||||
func mysql() logic.IEngine {
|
||||
return &engine.MConfig{
|
||||
User: "appuser", Password: "ABCabc01!",
|
||||
Host: "192.168.99.188", Port: 3306,
|
||||
DBName: "iot", Parameters: "charset=utf8mb4,utf8&parseTime=True&loc=Asia%2FShanghai",
|
||||
}
|
||||
}
|
||||
|
||||
func _init() {
|
||||
_db = GormEngine.NewEngine()(1, &GormEngine.EngineConfig{
|
||||
Debug: true,
|
||||
TablePrefix: "",
|
||||
Complex: false,
|
||||
MaxIdleConns: 50,
|
||||
MaxOpenConns: 150,
|
||||
MaxLifetime: 3600,
|
||||
}).Start(mysql())
|
||||
}
|
40
app/common/model/sys_auth.go
Normal file
40
app/common/model/sys_auth.go
Normal file
@ -0,0 +1,40 @@
|
||||
package model
|
||||
|
||||
type SysAuth struct {
|
||||
Model
|
||||
ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"-"`
|
||||
Kind SysAuthKind `gorm:"column:kind;type:tinyint(1);default:1;comment:类型(1:模块,2:权限)" json:"kind"`
|
||||
Name string `gorm:"column:name;type:varchar(30);default:null;comment:名称" json:"name"`
|
||||
Auth string `gorm:"column:auth;type:varchar(100);default:null;comment:权限/路由" json:"auth"`
|
||||
Sort int `gorm:"column:sort;type:tinyint(3);default:0;comment:排序" json:"-"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:备注信息" json:"remark"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
// SysAuthKind 权限分类
|
||||
type SysAuthKind int
|
||||
|
||||
const (
|
||||
// SysAuthKindForModule 模块
|
||||
SysAuthKindForModule SysAuthKind = iota + 1
|
||||
// SysAuthKindForAuth 权限
|
||||
SysAuthKindForAuth
|
||||
)
|
||||
|
||||
func (m *SysAuth) TableName() string {
|
||||
return "sys_auth"
|
||||
}
|
||||
|
||||
func (m *SysAuth) KindTitle() string {
|
||||
if m.Kind == SysAuthKindForModule {
|
||||
return "模块"
|
||||
} else if m.Kind == SysAuthKindForAuth {
|
||||
return "权限"
|
||||
}
|
||||
return "-"
|
||||
}
|
||||
|
||||
func NewSysAuth() *SysAuth {
|
||||
return &SysAuth{}
|
||||
}
|
21
app/common/model/sys_auth_rule.go
Normal file
21
app/common/model/sys_auth_rule.go
Normal file
@ -0,0 +1,21 @@
|
||||
package model
|
||||
|
||||
// SysAuthRule 用户角色权限规则,公用组件库-实例: `p, admin, tenant, data, read`
|
||||
type SysAuthRule struct {
|
||||
Model
|
||||
Ptype string `gorm:"column:ptype;type:varchar(100);default:null;comment:策略(组g/人员p)" json:"ptype"` // 相当于policy.csv文件中 一行中的 p
|
||||
V0 string `gorm:"column:v0;type:varchar(100);default:null;comment:角色/用户" json:"v0"` // 相当于policy.csv文件中 一行中的 role (角色)(例如:admin)
|
||||
V1 string `gorm:"column:v1;type:varchar(100);default:null;comment:平台/角色" json:"v1"` // 相当于policy.csv文件中 一行中的 sub (用户)(例如:tenant)
|
||||
V2 string `gorm:"column:v2;type:varchar(100);default:null;comment:路由/平台" json:"v2"` // 相当于policy.csv文件中 一行中的 obj (被操作的服务器资源)(例如:data)
|
||||
V3 string `gorm:"column:v3;type:varchar(100);default:null;comment:请求方式" json:"v3"` // 相当于policy.csv文件中 一行中的 act (操作者的行为)(例如:read)
|
||||
V4 string `gorm:"column:v4;type:varchar(100);default:null;comment:-" json:"v4"`
|
||||
V5 string `gorm:"column:v5;type:varchar(100);default:null;comment:-" json:"v5"`
|
||||
}
|
||||
|
||||
func (m *SysAuthRule) TableName() string {
|
||||
return "sys_auth_rule"
|
||||
}
|
||||
|
||||
func NewSysAuthRule() *SysAuthRule {
|
||||
return &SysAuthRule{}
|
||||
}
|
36
app/common/model/sys_config.go
Normal file
36
app/common/model/sys_config.go
Normal file
@ -0,0 +1,36 @@
|
||||
package model
|
||||
|
||||
// SysConfig 系统配置信息
|
||||
type SysConfig struct {
|
||||
Model
|
||||
Kind SysConfigKind `gorm:"column:kind;type:tinyint(3);default:0;comment:类型" json:"kind"`
|
||||
Name string `gorm:"column:name;type:varchar(30);default:null;comment:名称" json:"name"`
|
||||
Key string `gorm:"column:key;type:varchar(30);default:null;comment:标识" json:"key"`
|
||||
Value string `gorm:"column:value;type:varchar(255);default:null;comment:内容" json:"value"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
// SysConfigKind 系统配置分类
|
||||
type SysConfigKind int
|
||||
|
||||
const (
|
||||
// SysConfigKindForBasic 基本配置
|
||||
SysConfigKindForBasic SysConfigKind = iota + 1
|
||||
// SysConfigKindForWeChat 微信配置
|
||||
SysConfigKindForWeChat
|
||||
// SysConfigKindForAliPay 支付宝配置
|
||||
SysConfigKindForAliPay
|
||||
// SysConfigKindForGD 高德配置
|
||||
SysConfigKindForGaoDe
|
||||
// SysConfigKindForBaiDu 百度配置
|
||||
SysConfigKindForBaiDu
|
||||
)
|
||||
|
||||
func (m *SysConfig) TableName() string {
|
||||
return "sys_config"
|
||||
}
|
||||
|
||||
func NewSysConfig() *SysConfig {
|
||||
return &SysConfig{}
|
||||
}
|
21
app/common/model/sys_department.go
Normal file
21
app/common/model/sys_department.go
Normal file
@ -0,0 +1,21 @@
|
||||
package model
|
||||
|
||||
type SysDepartment struct {
|
||||
Model
|
||||
ModelTenant
|
||||
ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"parent_id"`
|
||||
Title string `gorm:"column:title;type:varchar(20);default:null;comment:部门名称" json:"title"`
|
||||
Name string `gorm:"column:name;type:varchar(20);default:null;comment:联系人" json:"name"`
|
||||
Mobile string `gorm:"column:mobile;type:varchar(15);default:null;comment:联系方式" json:"mobile"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:备注信息" json:"remark"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
func (m *SysDepartment) TableName() string {
|
||||
return m.NewTableName("sys_department")
|
||||
}
|
||||
|
||||
func NewSysDepartment() *SysDepartment {
|
||||
return &SysDepartment{}
|
||||
}
|
23
app/common/model/sys_log.go
Normal file
23
app/common/model/sys_log.go
Normal file
@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
// SysLog 系统日志
|
||||
type SysLog struct {
|
||||
Model
|
||||
ModelTenant
|
||||
UID uint64 `gorm:"column:uid;type:int;default:0;comment:用户uuid" json:"-"`
|
||||
Name string `gorm:"column:name;type:varchar(20);default:null;comment:真实姓名" json:"name"`
|
||||
Method string `gorm:"column:method;type:varchar(8);default:null;comment:请求方式" json:"method"`
|
||||
Path string `gorm:"column:path;type:varchar(8);default:0;comment:请求地址" json:"event"`
|
||||
Params string `gorm:"column:params;type:text;default:null;comment:参数信息" json:"params"`
|
||||
IP string `gorm:"column:ip;type:char(16);default:null;comment:IP地址" json:"ip"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
func (m *SysLog) TableName() string {
|
||||
return m.NewTableName("sys_log")
|
||||
}
|
||||
|
||||
func NewSysLog() *SysLog {
|
||||
return &SysLog{}
|
||||
}
|
59
app/common/model/sys_menu.go
Normal file
59
app/common/model/sys_menu.go
Normal file
@ -0,0 +1,59 @@
|
||||
package model
|
||||
|
||||
type SysMenu struct {
|
||||
Model
|
||||
SysMenuBasic
|
||||
Auth SysMenuAuth `gorm:"column:auth;type:tinyint(1);default:0;comment:查看权限(0:通用,1:超管)" json:"auth"`
|
||||
Sort int `gorm:"column:sort;type:tinyint(3);default:0;comment:排序,数值越大,优先排序" json:"sort"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:菜单备注" json:"remark"`
|
||||
Status SysMenuStatus `gorm:"column:status;type:tinyint(1);default:1;comment:状态" json:"status"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
type SysMenuBasic struct {
|
||||
ParentID uint64 `gorm:"column:parent_id;type:int;default:0;comment:父级ID" json:"parent_id"`
|
||||
Name string `gorm:"column:name;type:varchar(30);default:null;comment:菜单名" json:"name"`
|
||||
Kind SysMenuKind `gorm:"column:kind;type:tinyint(1);default:1;comment:类型(1:目录,2:菜单)" json:"kind"`
|
||||
Link string `gorm:"column:link;type:varchar(80);default:null;comment:菜单链接" json:"link"`
|
||||
Component string `gorm:"column:component;type:varchar(80);default:null;comment:组件标识" json:"component"`
|
||||
Icon string `gorm:"column:icon;type:varchar(50);default:null;comment:菜单图标" json:"icon"`
|
||||
}
|
||||
|
||||
// SysMenuKind 菜单类型
|
||||
type SysMenuKind int
|
||||
|
||||
const (
|
||||
// SysMenuKindForCatalogue 目录
|
||||
SysMenuKindForCatalogue SysMenuKind = iota + 1
|
||||
// SysMenuKindForMenu 菜单
|
||||
SysMenuKindForMenu
|
||||
)
|
||||
|
||||
// SysMenuAuth 菜单权限
|
||||
type SysMenuAuth int
|
||||
|
||||
const (
|
||||
// SysMenuAuthForOrdinary 普通权限
|
||||
SysMenuAuthForOrdinary SysMenuAuth = iota
|
||||
// SysMenuAuthForSystem 系统权限
|
||||
SysMenuAuthForSystem
|
||||
)
|
||||
|
||||
// SysMenuStatus 菜单状态
|
||||
type SysMenuStatus int
|
||||
|
||||
const (
|
||||
// SysMenuStatusForNormal 正常
|
||||
SysMenuStatusForNormal SysMenuStatus = iota + 1
|
||||
// SysMenuStatusForDisable 禁用
|
||||
SysMenuStatusForDisable
|
||||
)
|
||||
|
||||
func (m *SysMenu) TableName() string {
|
||||
return "sys_menu"
|
||||
}
|
||||
|
||||
func NewSysMenu() *SysMenu {
|
||||
return &SysMenu{}
|
||||
}
|
39
app/common/model/sys_role.go
Normal file
39
app/common/model/sys_role.go
Normal file
@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
type SysRole struct {
|
||||
Model
|
||||
ModelTenant
|
||||
Name string `gorm:"column:name;type:varchar(30);default:null;comment:角色名" json:"name"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:角色备注" json:"remark"`
|
||||
Sort int `gorm:"column:sort;type:tinyint(3);default:0;comment:排序" json:"-"`
|
||||
Status SysRoleStatus `gorm:"column:status;type:tinyint(1);default:0;comment:状态" json:"-"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
// SysRoleStatus 角色状态
|
||||
type SysRoleStatus int
|
||||
|
||||
const (
|
||||
// SysRoleStatusForNormal 正常
|
||||
SysRoleStatusForNormal SysRoleStatus = iota + 1
|
||||
// SysRoleStatusForDisable 禁用
|
||||
SysRoleStatusForDisable
|
||||
)
|
||||
|
||||
func (m *SysRole) TableName() string {
|
||||
return m.NewTableName("sys_role")
|
||||
}
|
||||
|
||||
func (m *SysRole) StatusTitle() string {
|
||||
if m.Status == SysRoleStatusForNormal {
|
||||
return "正常"
|
||||
} else if m.Status == SysRoleStatusForDisable {
|
||||
return "禁用"
|
||||
}
|
||||
return "-"
|
||||
}
|
||||
|
||||
func NewSysRole() *SysRole {
|
||||
return &SysRole{}
|
||||
}
|
18
app/common/model/sys_role_auth.go
Normal file
18
app/common/model/sys_role_auth.go
Normal file
@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
type SysRoleAuth struct {
|
||||
Model
|
||||
ModelTenant
|
||||
RoleID uint64 `gorm:"column:role_id;type:int;default:0;comment:角色ID" json:"-"`
|
||||
AuthID uint64 `gorm:"column:auth_id;type:int;default:0;comment:权限ID" json:"-"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
func (m *SysRoleAuth) TableName() string {
|
||||
return m.NewTableName("sys_role_auth")
|
||||
}
|
||||
|
||||
func NewSysRoleAuth() *SysRoleAuth {
|
||||
return &SysRoleAuth{}
|
||||
}
|
18
app/common/model/sys_role_menu.go
Normal file
18
app/common/model/sys_role_menu.go
Normal file
@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
type SysRoleMenu struct {
|
||||
Model
|
||||
ModelTenant
|
||||
RoleID uint64 `gorm:"column:role_id;type:int;default:0;comment:角色ID" json:"-"`
|
||||
MenuID uint64 `gorm:"column:menu_id;type:int;default:0;comment:菜单ID" json:"-"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
func (m *SysRoleMenu) TableName() string {
|
||||
return m.NewTableName("sys_role_menu")
|
||||
}
|
||||
|
||||
func NewSysRoleMenu() *SysRoleMenu {
|
||||
return &SysRoleMenu{}
|
||||
}
|
69
app/common/model/sys_tenant.go
Normal file
69
app/common/model/sys_tenant.go
Normal file
@ -0,0 +1,69 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"ArmedPolice/utils"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
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"`
|
||||
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"
|
||||
}
|
||||
|
||||
func (m *SysTenant) BeforeCreate(db *gorm.DB) error {
|
||||
snowflake, _ := utils.NewSnowflake(1)
|
||||
m.Key = utils.IntToString(snowflake.GetID())
|
||||
m.CreatedAt = time.Now()
|
||||
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{}
|
||||
}
|
17
app/common/model/sys_tenant_auth.go
Normal file
17
app/common/model/sys_tenant_auth.go
Normal file
@ -0,0 +1,17 @@
|
||||
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{}
|
||||
}
|
17
app/common/model/sys_tenant_menu.go
Normal file
17
app/common/model/sys_tenant_menu.go
Normal file
@ -0,0 +1,17 @@
|
||||
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{}
|
||||
}
|
60
app/common/model/sys_user.go
Normal file
60
app/common/model/sys_user.go
Normal file
@ -0,0 +1,60 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"ArmedPolice/utils"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SysUser struct {
|
||||
Model
|
||||
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"`
|
||||
Name string `gorm:"column:name;type:varchar(20);default:null;comment:真实姓名" json:"name"`
|
||||
Mobile string `gorm:"column:mobile;index:idx_sys_user_mobile;type:varchar(15);default:null;comment:联系方式" json:"mobile"`
|
||||
Email string `gorm:"column:email;type:varchar(50);default:null;comment:邮箱" json:"email"`
|
||||
Gender
|
||||
Password string `gorm:"column:password;type:varchar(100);default:null;comment:密码" json:"-"`
|
||||
Salt string `gorm:"column:salt;type:varchar(10);default:null;comment:盐值" json:"-"`
|
||||
IsAdmin SysUserAdministrator `gorm:"column:is_admin;type:tinyint(1);default:0;comment:管理员(0:普通用户,1:管理员)" json:"-"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:null;comment:备注" json:"-"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
type SysUserAdministrator int
|
||||
|
||||
const (
|
||||
// SysUserAdministratorForOrdinary 普通人员
|
||||
SysUserAdministratorForOrdinary SysUserAdministrator = iota
|
||||
// SysUserAdministratorForAdmin 管理员
|
||||
SysUserAdministratorForAdmin
|
||||
)
|
||||
|
||||
func (m *SysUser) TableName() string {
|
||||
return "sys_user"
|
||||
}
|
||||
|
||||
func (m *SysUser) BeforeCreate(db *gorm.DB) error {
|
||||
m.Pass()
|
||||
snowflake, _ := utils.NewSnowflake(1)
|
||||
m.UUID = uint64(snowflake.GetID())
|
||||
m.CreatedAt = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *SysUser) Pass() {
|
||||
m.Salt = utils.GetRandomString(8)
|
||||
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{}
|
||||
}
|
19
app/common/model/sys_user_login_log.go
Normal file
19
app/common/model/sys_user_login_log.go
Normal file
@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
type SysUserLoginLog struct {
|
||||
Model
|
||||
ModelTenant
|
||||
UID uint64 `gorm:"column:uid;type:int;default:0;comment:用户uuid" json:"-"`
|
||||
Equipment string `gorm:"column:equipment;type:char(10);default:null;comment:登录设备" json:"equipment"`
|
||||
IP string `gorm:"column:ip;type:char(16);default:null;comment:IP地址" json:"ip"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
func (m *SysUserLoginLog) TableName() string {
|
||||
return "sys_user_login_log"
|
||||
}
|
||||
|
||||
func NewSysUserLoginLog() *SysUserLoginLog {
|
||||
return &SysUserLoginLog{}
|
||||
}
|
18
app/common/model/sys_user_role.go
Normal file
18
app/common/model/sys_user_role.go
Normal file
@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
type SysUserRole struct {
|
||||
Model
|
||||
ModelTenant
|
||||
UID uint64 `gorm:"column:uid;type:int;default:0;comment:用户uuid" json:"-"`
|
||||
RoleID uint64 `gorm:"column:role_id;type:int;default:0;comment:角色ID" json:"-"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
func (m *SysUserRole) TableName() string {
|
||||
return m.NewTableName("sys_user_role")
|
||||
}
|
||||
|
||||
func NewSysUserRole() *SysUserRole {
|
||||
return &SysUserRole{}
|
||||
}
|
40
app/common/model/sys_user_tenant.go
Normal file
40
app/common/model/sys_user_tenant.go
Normal file
@ -0,0 +1,40 @@
|
||||
package model
|
||||
|
||||
type SysUserTenant struct {
|
||||
Model
|
||||
ModelTenant
|
||||
UID uint64 `gorm:"column:uid;type:int;default:0;comment:用户uuid" json:"-"`
|
||||
Department string `gorm:"column:department;type:varchar(100);default:null;comment:部门信息" json:"department"`
|
||||
Role string `gorm:"column:role;type:varchar(100);default:null;comment:角色信息" json:"role"`
|
||||
Identity SysUserTenantIdentity `gorm:"column:identity;type:tinyint(1);default:0;comment:用户身份(1:管理员,2:用户)" json:"-"`
|
||||
Status SysUserTenantStatus `gorm:"column:status;type:tinyint(1);default:1;comment:状态(1:启用,2:禁用)" json:"-"`
|
||||
ModelDeleted
|
||||
ModelAt
|
||||
}
|
||||
|
||||
type SysUserTenantIdentity int
|
||||
|
||||
const (
|
||||
// SysUserTenantIdentityForSystemAdmin 管理员
|
||||
SysUserTenantIdentityForSystemAdmin SysUserTenantIdentity = iota + 1
|
||||
// SysUserTenantIdentityForSystemUser 用户
|
||||
SysUserTenantIdentityForSystemUser
|
||||
)
|
||||
|
||||
// SysUserTenantStatus 状态
|
||||
type SysUserTenantStatus int
|
||||
|
||||
const (
|
||||
// SysUserTenantStatusForEnable 启用
|
||||
SysUserTenantStatusForEnable SysUserTenantStatus = iota + 1
|
||||
// SysUserTenantStatusForDisable 禁用
|
||||
SysUserTenantStatusForDisable
|
||||
)
|
||||
|
||||
func (m *SysUserTenant) TableName() string {
|
||||
return m.NewTableName("sys_user_tenant")
|
||||
}
|
||||
|
||||
func NewSysUserTenant() *SysUserTenant {
|
||||
return &SysUserTenant{}
|
||||
}
|
134
app/common/model/where.go
Normal file
134
app/common/model/where.go
Normal file
@ -0,0 +1,134 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ModelWhere
|
||||
type ModelWhere struct {
|
||||
Condition string `json:"condition"` // 条件
|
||||
Value interface{} `json:"value"` // 内容
|
||||
}
|
||||
|
||||
// ModelOrder
|
||||
type ModelOrder struct {
|
||||
Field string `json:"field"` // 字段值
|
||||
Mode OrderMode `json:"mode"` // 排序模式
|
||||
}
|
||||
|
||||
// ModelWhereOrder
|
||||
type ModelWhereOrder struct {
|
||||
Where *ModelWhere
|
||||
Order *ModelOrder
|
||||
}
|
||||
|
||||
// OrderMode
|
||||
type OrderMode string
|
||||
|
||||
const (
|
||||
// OrderModeToAsc asc
|
||||
OrderModeToAsc = "asc"
|
||||
// OrderModeToDesc desc
|
||||
OrderModeToDesc = "desc"
|
||||
)
|
||||
|
||||
// NewWhere where
|
||||
func NewWhere(filed string, value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: filed + " = ?",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// NewWhereLike like where
|
||||
func NewWhereLike(filed string, value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: filed + " LIKE ?",
|
||||
Value: "%" + fmt.Sprintf("%v", value) + "%",
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereIn(filed string, value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: filed + " IN ?",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereNotIn(filed string, value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: filed + " NOT IN ?",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereCondition(filed, condition string, value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: filed + " " + condition + " ?",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereValue(value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: "",
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereFindInSet(filed string, value interface{}) *ModelWhere {
|
||||
return &ModelWhere{
|
||||
Condition: fmt.Sprintf("FIND_IN_SET(?, %s)", filed),
|
||||
Value: value,
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereSectionAt(filed string, value []string) []*ModelWhere {
|
||||
return []*ModelWhere{
|
||||
&ModelWhere{
|
||||
Condition: filed + " >= ?",
|
||||
Value: value[0],
|
||||
},
|
||||
&ModelWhere{
|
||||
Condition: filed + " <= ?",
|
||||
Value: value[1],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewWhereSectionTime(filed string, value []string) []*ModelWhere {
|
||||
return []*ModelWhere{
|
||||
&ModelWhere{
|
||||
Condition: filed + " >= ?",
|
||||
Value: value[0] + " 00:00:00",
|
||||
},
|
||||
&ModelWhere{
|
||||
Condition: filed + " <= ?",
|
||||
Value: value[1] + " 23:59:59",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// NewOrder order Asc Or Desc
|
||||
func NewOrder(filed string, order OrderMode) *ModelOrder {
|
||||
return &ModelOrder{Field: filed, Mode: order}
|
||||
}
|
||||
|
||||
// NewOrderSplit param to split for order Asc Or Desc
|
||||
func NewOrderSplit(param string) *ModelOrder {
|
||||
params := strings.Split(param, "-")
|
||||
|
||||
if len(params) <= 1 {
|
||||
return nil
|
||||
}
|
||||
order := new(ModelOrder)
|
||||
|
||||
order.Field = params[0]
|
||||
order.Mode = OrderModeToAsc
|
||||
|
||||
if params[1] == OrderModeToDesc {
|
||||
order.Mode = OrderModeToDesc
|
||||
}
|
||||
return order
|
||||
}
|
100
app/controller/account.go
Normal file
100
app/controller/account.go
Normal file
@ -0,0 +1,100 @@
|
||||
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}}
|
||||
}
|
||||
}
|
60
app/controller/auth/base.go
Normal file
60
app/controller/auth/base.go
Normal file
@ -0,0 +1,60 @@
|
||||
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
|
||||
}
|
34
app/controller/auth/instance.go
Normal file
34
app/controller/auth/instance.go
Normal file
@ -0,0 +1,34 @@
|
||||
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}}
|
||||
}
|
||||
}
|
87
app/controller/auth/role.go
Normal file
87
app/controller/auth/role.go
Normal file
@ -0,0 +1,87 @@
|
||||
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}}
|
||||
}
|
||||
}
|
107
app/controller/auth/tenant.go
Normal file
107
app/controller/auth/tenant.go
Normal file
@ -0,0 +1,107 @@
|
||||
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}}
|
||||
}
|
||||
}
|
33
app/controller/base.go
Normal file
33
app/controller/base.go
Normal file
@ -0,0 +1,33 @@
|
||||
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)
|
||||
}
|
||||
}
|
64
app/controller/config.go
Normal file
64
app/controller/config.go
Normal file
@ -0,0 +1,64 @@
|
||||
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{}
|
||||
}
|
||||
}
|
57
app/controller/logs.go
Normal file
57
app/controller/logs.go
Normal file
@ -0,0 +1,57 @@
|
||||
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}}
|
||||
}
|
||||
}
|
87
app/controller/menu/base.go
Normal file
87
app/controller/menu/base.go
Normal file
@ -0,0 +1,87 @@
|
||||
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
|
||||
}
|
113
app/controller/menu/menu.go
Normal file
113
app/controller/menu/menu.go
Normal file
@ -0,0 +1,113 @@
|
||||
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}}
|
||||
}
|
||||
}
|
74
app/controller/menu/role.go
Normal file
74
app/controller/menu/role.go
Normal file
@ -0,0 +1,74 @@
|
||||
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}}
|
||||
}
|
||||
}
|
91
app/controller/menu/tenant.go
Normal file
91
app/controller/menu/tenant.go
Normal file
@ -0,0 +1,91 @@
|
||||
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}}
|
||||
}
|
||||
}
|
42
app/controller/menu/user.go
Normal file
42
app/controller/menu/user.go
Normal file
@ -0,0 +1,42 @@
|
||||
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}}
|
||||
}
|
||||
}
|
173
app/controller/role/instance.go
Normal file
173
app/controller/role/instance.go
Normal file
@ -0,0 +1,173 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
model2 "ArmedPolice/app/common/model"
|
||||
"ArmedPolice/app/controller"
|
||||
"ArmedPolice/app/model"
|
||||
"ArmedPolice/app/service"
|
||||
"ArmedPolice/serve/logger"
|
||||
"ArmedPolice/utils"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Instance struct{ *controller.Platform }
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
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
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewInstance() InstanceHandle {
|
||||
return func(session *service.Session) *Instance {
|
||||
return &Instance{Platform: &controller.Platform{Session: session}}
|
||||
}
|
||||
}
|
81
app/controller/role/user.go
Normal file
81
app/controller/role/user.go
Normal file
@ -0,0 +1,81 @@
|
||||
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}}
|
||||
}
|
||||
}
|
450
app/controller/tenant/instance.go
Normal file
450
app/controller/tenant/instance.go
Normal file
@ -0,0 +1,450 @@
|
||||
package tenant
|
||||
|
||||
import (
|
||||
model2 "ArmedPolice/app/common/model"
|
||||
"ArmedPolice/app/controller"
|
||||
cAuth "ArmedPolice/app/controller/auth"
|
||||
"ArmedPolice/app/controller/menu"
|
||||
"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 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
|
||||
}
|
||||
mSysTenant := model.NewSysTenant()
|
||||
|
||||
var count int64
|
||||
|
||||
if err := model2.Count(mSysTenant.SysTenant, &count, model2.NewWhere("parent_id", tenantID)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return int(count) <= srcValue, nil
|
||||
}
|
||||
|
||||
// List 列表信息
|
||||
func (c *Instance) List(name string, status, page, pageSize int) (*controller.ReturnPages, error) {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
|
||||
var count int64
|
||||
|
||||
where := []*model2.ModelWhere{model2.NewWhere("t.parent_id", 0)}
|
||||
|
||||
if name != "" {
|
||||
where = append(where, model2.NewWhereLike("t.name", name))
|
||||
}
|
||||
if status > 0 {
|
||||
where = append(where, model2.NewWhere("t.status", status))
|
||||
}
|
||||
out, err := mSysTenant.Tenants(page, pageSize, &count, where...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := make([]*InstanceInfo, 0)
|
||||
|
||||
for _, v := range out {
|
||||
v.Image.Image = v.Image.Analysis(config.SettingInfo.Domain)
|
||||
|
||||
list = append(list, &InstanceInfo{SysTenantInfo: v, Config: v.ConfigInfo()})
|
||||
}
|
||||
return &controller.ReturnPages{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)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Edit 修改信息
|
||||
func (c *Instance) Edit(params *InstanceParams) error {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
mSysTenant.ID = params.ID
|
||||
|
||||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("租户/公司信息不存在")
|
||||
} else if c.TenantID > 0 {
|
||||
if mSysTenant.ParentID <= 0 {
|
||||
return errors.New("不可修改其他租户/公司的信息")
|
||||
} else if c.TenantID != mSysTenant.ParentID {
|
||||
return errors.New("不可修改其他租户/公司的客户信息")
|
||||
}
|
||||
}
|
||||
if mSysTenant.Name != params.Name {
|
||||
if isExist, err = model2.FirstWhere(mSysTenant.SysTenant, model2.NewWhere("name", params.Name)); err != nil {
|
||||
return err
|
||||
} else if isExist {
|
||||
return errors.New("该租户/公司名称已存在")
|
||||
}
|
||||
}
|
||||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{
|
||||
"name": params.Name, "image": params.Image, "remark": params.Remark, "updated_at": time.Now(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// EditPassword 修改信息
|
||||
func (c *Instance) EditPassword(params *InstanceParams) error {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
mSysTenant.ID = params.ID
|
||||
|
||||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("租户/公司信息不存在")
|
||||
} else if c.TenantID > 0 {
|
||||
if mSysTenant.ParentID <= 0 {
|
||||
return errors.New("不可修改其他租户/公司的用户密码信息")
|
||||
} else if c.TenantID != mSysTenant.ParentID {
|
||||
return errors.New("不可修改其他租户/公司的用户密码信息")
|
||||
}
|
||||
}
|
||||
if params.Password != params.RepeatPwd {
|
||||
return errors.New("密码不一致")
|
||||
}
|
||||
// 查询该租户下管理员信息
|
||||
mSysUserTenant := model.NewSysUserTenant()
|
||||
|
||||
if isExist, err = model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "uid", "identity"},
|
||||
model2.NewWhere("tenant_id", params.ID), model2.NewWhere("identity", model2.SysUserTenantIdentityForSystemAdmin)); err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("该租户/公司下管理员信息不存在或已被删除")
|
||||
}
|
||||
mSysUser := model.NewSysUser()
|
||||
mSysUser.Password = params.Password
|
||||
mSysUser.Pass()
|
||||
|
||||
if err = model2.UpdatesWhere(mSysUser.SysUser, map[string]interface{}{
|
||||
"password": mSysUser.Password, "salt": mSysUser.Salt, "updated_at": time.Now(),
|
||||
}, []*model2.ModelWhere{model2.NewWhere("uuid", mSysUserTenant.UID)}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Detail 详细信息
|
||||
func (c *Instance) Detail(id uint64, tType InstanceDetailType, page, pageSize int, name string, status int) (interface{}, error) {
|
||||
handle, has := instanceDetailGetHandle[tType]
|
||||
|
||||
if !has {
|
||||
return nil, errors.New(fmt.Sprintf("Unknown Tenant Detail Type:%d", tType))
|
||||
}
|
||||
out, err := handle(id)(page, pageSize, name, status)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Renewal 续期操作
|
||||
func (c *Instance) Renewal(id uint64, deadline string) error {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
mSysTenant.ID = id
|
||||
|
||||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("租户/公司信息不存在")
|
||||
} else if c.TenantID > 0 {
|
||||
if mSysTenant.ParentID <= 0 {
|
||||
return errors.New("非超级管理员,不可操作")
|
||||
} else if c.TenantID != mSysTenant.ParentID {
|
||||
return errors.New("非法操作,不可续期他人客户使用期限")
|
||||
}
|
||||
}
|
||||
now := time.Now()
|
||||
|
||||
updates := make(map[string]interface{}, 0)
|
||||
updates["updated_at"] = now
|
||||
|
||||
_deadline := utils.DateTimeToTime(deadline + " 23:59:59")
|
||||
|
||||
if _deadline.Before(mSysTenant.Deadline) {
|
||||
return errors.New("续期时间异常")
|
||||
}
|
||||
updates["deadline"] = _deadline
|
||||
|
||||
if mSysTenant.Status != model2.SysTenantStatusForNormal && _deadline.After(now) {
|
||||
updates["status"] = model2.SysTenantStatusForNormal
|
||||
}
|
||||
if err = model2.Updates(mSysTenant.SysTenant, updates); err != nil {
|
||||
return err
|
||||
}
|
||||
service.Publish(config.EventForRedisListProduce, config.RedisKeyForTenant, mSysTenant.Key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartUp 启用处理
|
||||
func (c *Instance) StartUp(id uint64) error {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
mSysTenant.ID = id
|
||||
|
||||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("租户/公司/客户信息不存在")
|
||||
} else if c.TenantID > 0 {
|
||||
if mSysTenant.ParentID <= 0 {
|
||||
return errors.New("非超级管理员,不可操作")
|
||||
} else if c.TenantID != mSysTenant.ParentID {
|
||||
return errors.New("不可启用其他租户/公司客户")
|
||||
}
|
||||
} else if mSysTenant.Status == model2.SysTenantStatusForNormal {
|
||||
return errors.New("该租户/公司/客户已是启用状态")
|
||||
}
|
||||
status := model2.SysTenantStatusForNormal
|
||||
|
||||
now := time.Now()
|
||||
|
||||
if mSysTenant.Deadline.Before(now) {
|
||||
status = model2.SysTenantStatusForExpired
|
||||
}
|
||||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{
|
||||
"status": status, "updated_at": now,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Disable 禁用处理
|
||||
func (c *Instance) Disable(id uint64) error {
|
||||
mSysTenant := model.NewSysTenant()
|
||||
mSysTenant.ID = id
|
||||
|
||||
isExist, err := model2.FirstWhere(mSysTenant.SysTenant)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("租户/公司/客户信息不存在")
|
||||
} else if c.TenantID > 0 {
|
||||
if mSysTenant.ParentID <= 0 {
|
||||
return errors.New("非超级管理员,不可操作")
|
||||
} else if c.TenantID != mSysTenant.ParentID {
|
||||
return errors.New("不可启用其他租户/公司/客户")
|
||||
}
|
||||
} else if mSysTenant.Status == model2.SysTenantStatusForDisable {
|
||||
return errors.New("该租户/公司/客户已是禁用状态")
|
||||
}
|
||||
if err = model2.Updates(mSysTenant.SysTenant, map[string]interface{}{
|
||||
"status": model2.SysTenantStatusForDisable, "updated_at": time.Now(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO:推送用户强制退出,并强行删除所有产品数据
|
||||
service.Publish(config.EventForRedisListDestroy, config.RedisKeyForTenant, mSysTenant.Key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MemberBind 人员绑定/解绑
|
||||
func (c *Instance) MemberBind(id uint64, status int) error {
|
||||
mSysUserTenant := model.NewSysUserTenant()
|
||||
mSysUserTenant.ID = id
|
||||
|
||||
isExist, err := model2.FirstField(mSysUserTenant.SysUserTenant, []string{"id", "tenant_id", "identity"})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isExist {
|
||||
return errors.New("用户信息不存在")
|
||||
}
|
||||
if model2.SysUserTenantStatus(status) == mSysUserTenant.Status {
|
||||
return errors.New("状态异常,不可操作")
|
||||
}
|
||||
if err := model2.Updates(mSysUserTenant.SysUserTenant, map[string]interface{}{
|
||||
"status": status, "updated_at": time.Now(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewInstance() InstanceHandle {
|
||||
return func(session *service.Session) *Instance {
|
||||
return &Instance{Platform: &controller.Platform{Session: session}}
|
||||
}
|
||||
}
|
20
app/controller/tenant/struct.go
Normal file
20
app/controller/tenant/struct.go
Normal file
@ -0,0 +1,20 @@
|
||||
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
|
||||
}
|
44
app/controller/tenant/sub.go
Normal file
44
app/controller/tenant/sub.go
Normal file
@ -0,0 +1,44 @@
|
||||
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
|
||||
}
|
249
app/controller/user/instance.go
Normal file
249
app/controller/user/instance.go
Normal file
@ -0,0 +1,249 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
model2 "ArmedPolice/app/common/model"
|
||||
"ArmedPolice/app/controller"
|
||||
"ArmedPolice/app/model"
|
||||
"ArmedPolice/app/service"
|
||||
"ArmedPolice/serve/orm"
|
||||
"ArmedPolice/utils"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Instance struct{ *controller.Platform }
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
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 NewInstance() InstanceHandle {
|
||||
return func(session *service.Session) *Instance {
|
||||
return &Instance{Platform: &controller.Platform{Session: session}}
|
||||
}
|
||||
}
|
47
app/controller/user/person.go
Normal file
47
app/controller/user/person.go
Normal file
@ -0,0 +1,47 @@
|
||||
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}
|
||||
}
|
||||
}
|
87
app/handle/captcha.go
Normal file
87
app/handle/captcha.go
Normal file
@ -0,0 +1,87 @@
|
||||
package handle
|
||||
|
||||
import (
|
||||
"ArmedPolice/app/service"
|
||||
"ArmedPolice/config"
|
||||
"ArmedPolice/serve/cache"
|
||||
"ArmedPolice/utils"
|
||||
)
|
||||
|
||||
type ICaptcha interface {
|
||||
validate() (bool, error)
|
||||
}
|
||||
|
||||
type (
|
||||
// Captcha 验证码
|
||||
Captcha struct{}
|
||||
|
||||
// CaptchaSms 短信验证码
|
||||
CaptchaSms struct {
|
||||
Mobile string `json:"mobile"`
|
||||
Captcha string `json:"captcha"`
|
||||
}
|
||||
|
||||
// CaptchaImage 图形验证码
|
||||
CaptchaImage struct {
|
||||
Key string `json:"key"`
|
||||
Captcha string `json:"captcha"`
|
||||
}
|
||||
)
|
||||
|
||||
type SmsCallback func(content string) error
|
||||
|
||||
const (
|
||||
// SmsCaptchaEffectiveTime 短信验证码有效时间
|
||||
SmsCaptchaEffectiveTime int = 3600 * 3
|
||||
)
|
||||
|
||||
func (this *CaptchaSms) validate() (bool, error) {
|
||||
code, err := cache.Cache.Get(this.Mobile)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if this.Captcha != code {
|
||||
return false, nil
|
||||
}
|
||||
return true, cache.Cache.Del(this.Mobile)
|
||||
}
|
||||
|
||||
func (this *CaptchaImage) validate() (bool, error) {
|
||||
return service.Captcha(&service.CaptchaInfo{Key: this.Key, Captcha: this.Captcha}).Validate(), nil
|
||||
}
|
||||
|
||||
// Sms 短信
|
||||
func (this *Captcha) Sms(length int, mobile string, callback SmsCallback) error {
|
||||
code := utils.GetRandomCode(length)
|
||||
// 存储redis
|
||||
if err := cache.Cache.Set(mobile, code, SmsCaptchaEffectiveTime); err != nil {
|
||||
return err
|
||||
}
|
||||
// 发送短信
|
||||
//NewSms().Handle(mobile)
|
||||
return callback(mobile)
|
||||
}
|
||||
|
||||
// Image 图形
|
||||
func (this *Captcha) Image(captchaType service.CaptchaType) (*CaptchaImage, error) {
|
||||
captcha, err := service.Captcha(captchaType).Create()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &CaptchaImage{Key: captcha.Key, Captcha: captcha.Captcha}, nil
|
||||
}
|
||||
|
||||
// Validate 验证
|
||||
func (this *Captcha) Validate(captcha ICaptcha) (bool, error) {
|
||||
if config.IsDebug() {
|
||||
return true, nil
|
||||
}
|
||||
return captcha.validate()
|
||||
}
|
||||
|
||||
func NewCaptcha() *Captcha {
|
||||
return &Captcha{}
|
||||
}
|
62
app/model/sys_auth.go
Normal file
62
app/model/sys_auth.go
Normal file
@ -0,0 +1,62 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SysAuth struct {
|
||||
*model.SysAuth
|
||||
}
|
||||
|
||||
// SysAuthScene 信息
|
||||
type SysAuthScene struct {
|
||||
*model.SysAuth
|
||||
SceneID uint64 `json:"scene_id"`
|
||||
}
|
||||
|
||||
// TenantAuth 租户权限
|
||||
func (m *SysAuth) TenantAuth(tenantID uint64) ([]*SysAuthScene, error) {
|
||||
mSysTenantAuth := NewSysTenantAuth()
|
||||
|
||||
out := make([]*SysAuthScene, 0)
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()+" AS a").
|
||||
Select("a.*, r_a.id AS scene_id").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS t_a ON t_a.auth_id = a.id AND t_a.tenant_id = %d AND t_a.is_deleted = %d",
|
||||
mSysTenantAuth.TableName(), tenantID, model.DeleteStatusForNot)).
|
||||
Where("a.is_deleted = ?", model.DeleteStatusForNot)
|
||||
|
||||
if err := db.Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// RoleAuth 角色权限
|
||||
func (m *SysAuth) RoleAuth(tenantID, roleID uint64) ([]*SysAuthScene, error) {
|
||||
mSysTenantAuth := NewSysTenantAuth()
|
||||
|
||||
mSysRoleAuth := NewSysRoleAuth()
|
||||
|
||||
out := make([]*SysAuthScene, 0)
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()+" AS a").
|
||||
Select("a.*, r_a.id AS scene_id").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS t_a ON t_a.auth_id = a.id AND t_a.tenant_id = %d AND t_a.is_deleted = %d",
|
||||
mSysTenantAuth.TableName(), tenantID, model.DeleteStatusForNot)).
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS r_a ON r_a.auth_id = a.id AND r_a.role_id = %d AND r_a.is_deleted = %d",
|
||||
mSysRoleAuth.TableName(), roleID, model.DeleteStatusForNot)).
|
||||
Where("a.is_deleted = ?", model.DeleteStatusForNot).
|
||||
Where("t_a.id > ?", 0)
|
||||
|
||||
if err := db.Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewSysAuth() *SysAuth {
|
||||
return &SysAuth{SysAuth: model.NewSysAuth()}
|
||||
}
|
11
app/model/sys_config.go
Normal file
11
app/model/sys_config.go
Normal file
@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
import "TenantServe/app/common/model"
|
||||
|
||||
type SysConfig struct {
|
||||
*model.SysConfig
|
||||
}
|
||||
|
||||
func NewSysConfig() *SysConfig {
|
||||
return &SysConfig{}
|
||||
}
|
11
app/model/sys_deparement.go
Normal file
11
app/model/sys_deparement.go
Normal file
@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
import "TenantServe/app/common/model"
|
||||
|
||||
type SysDepartment struct {
|
||||
*model.SysDepartment
|
||||
}
|
||||
|
||||
func NewSysDepartment() *SysDepartment {
|
||||
return &SysDepartment{SysDepartment: model.NewSysDepartment()}
|
||||
}
|
13
app/model/sys_log.go
Normal file
13
app/model/sys_log.go
Normal file
@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"ArmedPolice/app/common/model"
|
||||
)
|
||||
|
||||
type SysLog struct {
|
||||
*model.SysLog
|
||||
}
|
||||
|
||||
func NewSysLog() *SysLog {
|
||||
return &SysLog{}
|
||||
}
|
117
app/model/sys_menu.go
Normal file
117
app/model/sys_menu.go
Normal file
@ -0,0 +1,117 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SysMenu struct {
|
||||
*model.SysMenu
|
||||
}
|
||||
|
||||
type SysMenuScene struct {
|
||||
ID uint64 `json:"id"`
|
||||
*model.SysMenuBasic
|
||||
SceneID uint64 `json:"scene_id"` // 场景(租户,角色)
|
||||
}
|
||||
|
||||
// Recursion 递归查询子菜单
|
||||
func (m *SysMenu) Recursion(id uint64) {
|
||||
//SELECT
|
||||
//t3.id, t3.parent_id, t3.`name`, t3.kind
|
||||
//FROM
|
||||
//(SELECT
|
||||
//t1.id, t1.parent_id, t1.name, t1.kind,
|
||||
// IF(FIND_IN_SET( parent_id, @pids ) > 0, @pids := concat( @pids, ',', id ), 0 ) AS is_child
|
||||
//FROM
|
||||
//(SELECT id, parent_id, `name`, kind FROM sys_menu WHERE is_deleted = 0 ORDER BY parent_id ASC, sort DESC) AS t1,
|
||||
// (SELECT @pids := 1) AS t2
|
||||
//) AS t3
|
||||
//WHERE is_child != 0
|
||||
}
|
||||
|
||||
// SystemMenu 系统菜单
|
||||
func (m *SysMenu) SystemMenu(where ...*model.ModelWhere) ([]*model.SysMenu, error) {
|
||||
out := make([]*model.SysMenu, 0)
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()).
|
||||
Where("status = ? AND is_deleted = ?", model.SysMenuStatusForNormal, model.DeleteStatusForNot)
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
if err := db.Order("parent_id " + model.OrderModeToAsc).Order("sort " + model.OrderModeToDesc).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// TenantMenu 租户菜单
|
||||
func (m *SysMenu) TenantMenu(tenantID uint64) ([]*SysMenuScene, error) {
|
||||
mSysTenantMenu := NewSysTenantMenu()
|
||||
|
||||
out := make([]*SysMenuScene, 0)
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()+" m").
|
||||
Select("m.id, m.parent_id, m.name, m.kind, m.link, m.component, m.icon, t_m.id AS scene_id").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS t_m ON m.id = t_m.menu_id AND t_m.tenant_id = %d AND t_m.is_deleted = %d",
|
||||
mSysTenantMenu.TableName(), tenantID, model.DeleteStatusForNot)).
|
||||
Where("m.status = ? AND m.is_deleted = ?", model.SysMenuStatusForNormal, model.DeleteStatusForNot)
|
||||
|
||||
if err := db.Order("m.parent_id " + model.OrderModeToAsc).Order("m.sort " + model.OrderModeToDesc).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// RoleMenu 角色菜单
|
||||
func (m *SysMenu) RoleMenu(tenantID uint64, roleID uint64) ([]*SysMenuScene, error) {
|
||||
mSysTenantMenu := NewSysTenantMenu()
|
||||
|
||||
mSysRoleMenu := NewSysRoleMenu()
|
||||
|
||||
out := make([]*SysMenuScene, 0)
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()+" AS m").
|
||||
Select("m.id, m.parent_id, m.name, m.kind, m.link, m.component, m.icon, r_m.id AS scene_id").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS t_m ON m.id = t_m.menu_id AND t_m.tenant_id = %d AND t_m.is_deleted = %d",
|
||||
mSysTenantMenu.TableName(), tenantID, model.DeleteStatusForNot)).
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS r_m ON m.id = r_m.menu_id AND r_m.role_id = %d AND r_m.is_deleted = %d",
|
||||
mSysRoleMenu.TableName(), roleID, model.DeleteStatusForNot)).
|
||||
Where("m.status = ? AND m.is_deleted = ?", model.SysMenuStatusForNormal, model.DeleteStatusForNot).
|
||||
Where("t_m.id > ?", 0)
|
||||
|
||||
if err := db.Order("m.parent_id " + model.OrderModeToAsc).Order("m.sort " + model.OrderModeToDesc).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// UserMenu 用户菜单
|
||||
func (m *SysMenu) UserMenu(uid uint64) ([]*SysMenuScene, error) {
|
||||
mSysUserRole := NewSysUserRole()
|
||||
|
||||
mSysRoleMenu := NewSysRoleMenu()
|
||||
|
||||
out := make([]*SysMenuScene, 0)
|
||||
|
||||
db := orm.GetDB().Table(mSysUserRole.TableName()+" AS u_r").
|
||||
Select("m.id, m.parent_id, m.name, m.kind, m.link, m.component, m.icon").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS r_m ON u_r.role_id = r_m.id AND r_m.is_deletd = %d",
|
||||
mSysRoleMenu.TableName(), model.DeleteStatusForNot)).
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS m ON r_m.menu_id = m.id AND m.status = %d AND m.is_deleted = %d",
|
||||
m.TableName(), model.SysMenuStatusForNormal, model.DeleteStatusForNot)).
|
||||
Where("u_r.uid = ? AND u_r.is_deleted = ?", uid, model.DeleteStatusForNot)
|
||||
|
||||
if err := db.Order("m.parent_id " + model.OrderModeToAsc).Order("m.sort " + model.OrderModeToDesc).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewSysMenu() *SysMenu {
|
||||
return &SysMenu{SysMenu: model.NewSysMenu()}
|
||||
}
|
45
app/model/sys_role.go
Normal file
45
app/model/sys_role.go
Normal file
@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SysRole struct {
|
||||
*model.SysRole
|
||||
}
|
||||
|
||||
// SysRoleBasic 基本信息
|
||||
type SysRoleBasic struct {
|
||||
ID uint64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// SysRoleUserInfo 用户角色信息
|
||||
type SysRoleUserInfo struct {
|
||||
*SysRoleBasic
|
||||
UserRoleID uint64 `json:"user_role_id"`
|
||||
}
|
||||
|
||||
// UserRole 用户角色信息
|
||||
func (m *SysRole) UserRole(uid uint64) ([]*SysRoleUserInfo, error) {
|
||||
mSysUserRole := NewSysUserRole()
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()+" AS r").
|
||||
Select("r.is, r.name, u_r.id AS user_role_id").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS u_r ON r.id = u_r.role_id AND u_r.uid = %d AND u_r.is_deleted = %d",
|
||||
mSysUserRole.TableName(), uid, model.DeleteStatusForNot)).
|
||||
Where("r.is_deleted = ?", model.DeleteStatusForNot)
|
||||
|
||||
out := make([]*SysRoleUserInfo, 0)
|
||||
|
||||
if err := db.Order("r.id " + model.OrderModeToDesc).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewSysRole() *SysRole {
|
||||
return &SysRole{SysRole: model.NewSysRole()}
|
||||
}
|
47
app/model/sys_role_auth.go
Normal file
47
app/model/sys_role_auth.go
Normal file
@ -0,0 +1,47 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SysRoleAuth struct {
|
||||
*model.SysRoleAuth
|
||||
}
|
||||
|
||||
// SysRoleAuths 权限信息
|
||||
type SysRoleAuths struct {
|
||||
ID uint64 `json:"id"`
|
||||
RoleID uint64 `json:"role_id"`
|
||||
Auth string `json:"auth"`
|
||||
}
|
||||
|
||||
// Auths 权限信息
|
||||
func (m *SysRoleAuth) Auths(where ...*model.ModelWhere) ([]*SysRoleAuths, error) {
|
||||
mSysRole := NewSysRole()
|
||||
|
||||
mSysAuth := NewSysAuth()
|
||||
|
||||
db := orm.GetDB().Table(m.TableName()+" AS r_a").
|
||||
Select("r_a.id, r_a.role_id, a.auth").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS r ON r_a.role_id = r.id", mSysRole.TableName())).
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS a ON r_a.auth_id = a.id", mSysAuth.TableName())).
|
||||
Where("r_a.is_deleted = ?", model.DeleteStatusForNot)
|
||||
|
||||
out := make([]*SysRoleAuths, 0)
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
if err := db.Order("r_a.id " + model.OrderModeToDesc).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewSysRoleAuth() *SysRoleAuth {
|
||||
return &SysRoleAuth{SysRoleAuth: model.NewSysRoleAuth()}
|
||||
}
|
13
app/model/sys_role_menu.go
Normal file
13
app/model/sys_role_menu.go
Normal file
@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
model2 "TenantServe/app/common/model"
|
||||
)
|
||||
|
||||
type SysRoleMenu struct {
|
||||
*model2.SysRoleMenu
|
||||
}
|
||||
|
||||
func NewSysRoleMenu() *SysRoleMenu {
|
||||
return &SysRoleMenu{SysRoleMenu: model2.NewSysRoleMenu()}
|
||||
}
|
85
app/model/sys_tenant.go
Normal file
85
app/model/sys_tenant.go
Normal file
@ -0,0 +1,85 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SysTenant struct {
|
||||
*model.SysTenant
|
||||
}
|
||||
|
||||
type (
|
||||
// SysTenantBasic 租户基本信息
|
||||
SysTenantBasic struct {
|
||||
}
|
||||
// SysTenantInfo 租户信息
|
||||
SysTenantInfo struct {
|
||||
*model.SysTenant
|
||||
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()}
|
||||
}
|
11
app/model/sys_tenant_auth.go
Normal file
11
app/model/sys_tenant_auth.go
Normal file
@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
import "TenantServe/app/common/model"
|
||||
|
||||
type SysTenantAuth struct {
|
||||
*model.SysTenantAuth
|
||||
}
|
||||
|
||||
func NewSysTenantAuth() *SysTenantAuth {
|
||||
return &SysTenantAuth{SysTenantAuth: model.NewSysTenantAuth()}
|
||||
}
|
11
app/model/sys_tenant_menu.go
Normal file
11
app/model/sys_tenant_menu.go
Normal file
@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
import "TenantServe/app/common/model"
|
||||
|
||||
type SysTenantMenu struct {
|
||||
*model.SysTenantMenu
|
||||
}
|
||||
|
||||
func NewSysTenantMenu() *SysTenantMenu {
|
||||
return &SysTenantMenu{SysTenantMenu: model.NewSysTenantMenu()}
|
||||
}
|
40
app/model/sys_user.go
Normal file
40
app/model/sys_user.go
Normal file
@ -0,0 +1,40 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
model2 "TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"TenantServe/utils"
|
||||
"errors"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// SysUser 用户信息
|
||||
type SysUser struct {
|
||||
*model2.SysUser
|
||||
}
|
||||
|
||||
func (m *SysUser) ValidatePassword(password string) bool {
|
||||
return utils.HashCompare([]byte(m.Password), []byte(utils.Md5String(password, m.Salt)))
|
||||
}
|
||||
|
||||
func (m *SysUser) IsAdminUser() bool {
|
||||
return m.IsAdmin == model2.SysUserAdministratorForAdmin
|
||||
}
|
||||
|
||||
func (m *SysUser) GetByAccountOrMobile(param string) (bool, error) {
|
||||
db := orm.GetDB().Table(m.TableName()).Where("(account = ? OR mobile = ?)", param, param).
|
||||
Where("is_deleted = ?", model2.DeleteStatusForNot)
|
||||
|
||||
if err := db.First(m.SysUser).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func NewSysUser() *SysUser {
|
||||
return &SysUser{SysUser: model2.NewSysUser()}
|
||||
}
|
45
app/model/sys_user_login_log.go
Normal file
45
app/model/sys_user_login_log.go
Normal file
@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"TenantServe/app/common/model"
|
||||
"TenantServe/serve/orm"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type SysUserLoginLog struct {
|
||||
*model.SysUserLoginLog
|
||||
}
|
||||
|
||||
type SysUserLoginLogInfo struct {
|
||||
*model.SysUserLoginLog
|
||||
TenantName string `json:"tenant_name"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
// Logs 日志信息
|
||||
func (m *SysUserLoginLog) Logs(page, pageSize int, count *int64, where ...*model.ModelWhere) ([]*SysUserLoginLogInfo, error) {
|
||||
db := orm.GetDB().Table(m.TableName()+" AS l").
|
||||
Select("l.*, t.name AS tenant_name, u.name AS username").
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS t ON l.tenant_id = t.id", NewSysTenant().TableName())).
|
||||
Joins(fmt.Sprintf("LEFT JOIN %s AS u ON l.uid = u.uuid", NewSysUser().TableName())).
|
||||
Where("l.is_deleted = ?", model.DeleteStatusForNot)
|
||||
|
||||
if len(where) > 0 {
|
||||
for _, wo := range where {
|
||||
db = db.Where(wo.Condition, wo.Value)
|
||||
}
|
||||
}
|
||||
out := make([]*SysUserLoginLogInfo, 0)
|
||||
|
||||
if err := db.Count(count).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := db.Order("l.id " + model.OrderModeToDesc).Offset((page - 1) * pageSize).Limit(pageSize).Scan(&out).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func NewSysUserLoginLog() *SysUserLoginLog {
|
||||
return &SysUserLoginLog{SysUserLoginLog: model.NewSysUserLoginLog()}
|
||||
}
|
13
app/model/sys_user_role.go
Normal file
13
app/model/sys_user_role.go
Normal file
@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
model2 "TenantServe/app/common/model"
|
||||
)
|
||||
|
||||
type SysUserRole struct {
|
||||
*model2.SysUserRole
|
||||
}
|
||||
|
||||
func NewSysUserRole() *SysUserRole {
|
||||
return &SysUserRole{SysUserRole: model2.NewSysUserRole()}
|
||||
}
|
83
app/model/sys_user_tenant.go
Normal file
83
app/model/sys_user_tenant.go
Normal file
@ -0,0 +1,83 @@
|
||||
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()}
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"Edu/utils"
|
||||
"ArmedPolice/utils"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
ID uint64 `json:"id"` // 用户ID
|
||||
OpenID string `json:"open_id"`
|
||||
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"` // 用户信息
|
||||
}
|
||||
@ -21,8 +21,8 @@ func (this *Session) UnmarshalBinary(data []byte) error {
|
||||
return utils.FromJSONBytes(data, this)
|
||||
}
|
||||
|
||||
func (this *Session) IDToString() string {
|
||||
return utils.UintToString(this.ID)
|
||||
func (this *Session) UIDToString() string {
|
||||
return utils.UintToString(this.UID)
|
||||
}
|
||||
|
||||
func NewSession() *Session {
|
||||
|
4
serve/cache/init.go
vendored
4
serve/cache/init.go
vendored
@ -1,8 +1,8 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"Edu/config"
|
||||
"Edu/serve/cache/logic"
|
||||
"ArmedPolice/config"
|
||||
"ArmedPolice/serve/cache/logic"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"Edu/tools/ip"
|
||||
"ArmedPolice/tools/ip"
|
||||
)
|
||||
|
||||
func initIP() {
|
||||
|
Reference in New Issue
Block a user