refactor: reorganize modules and add Linux build tooling
This commit is contained in:
89
module/base/mgt/internal/logic/application/create.go
Normal file
89
module/base/mgt/internal/logic/application/create.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Create(c *gin.Context) {
|
||||
var (
|
||||
request = types.ApplicationRequest{}
|
||||
data = models.MgtApplication{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 判断应用是否已经存在(包括软删除的记录)
|
||||
db := models.DBService.Model(&models.MgtApplication{})
|
||||
if err = db.Where("title = ? or workspace = ?", request.Title, request.Workspace).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
// 未找到记录(包括软删除的),检查是否有软删除的记录
|
||||
var deletedData models.MgtApplication
|
||||
// 检查 workspace 是否被软删除(workspace 有唯一索引)
|
||||
if request.Workspace != "" {
|
||||
if err = models.DBService.Unscoped().Where("workspace = ?", request.Workspace).First(&deletedData).Error; err == nil {
|
||||
// 存在软删除的记录,先物理删除它,以便可以重新创建
|
||||
if err = models.DBService.Unscoped().Delete(&deletedData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
printer.Info("已物理删除软删除的应用记录: ID=%d, workspace=%s", deletedData.ID, deletedData.Workspace)
|
||||
}
|
||||
}
|
||||
// 检查 title 是否被软删除(如果 title 和 workspace 不同)
|
||||
if request.Title != "" && request.Title != request.Workspace {
|
||||
if err = models.DBService.Unscoped().Where("title = ?", request.Title).First(&deletedData).Error; err == nil {
|
||||
// 存在软删除的记录,先物理删除它
|
||||
if err = models.DBService.Unscoped().Delete(&deletedData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
printer.Info("已物理删除软删除的应用记录: ID=%d, title=%s", deletedData.ID, deletedData.Title)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 找到未删除的记录,说明应用已存在
|
||||
printer.Info("应用已存在: title=%s, workspace=%s", request.Title, request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
// 新增应用
|
||||
var dataModel = models.MgtApplication{
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Identity: utils.UUID(), Status: 1},
|
||||
Title: request.Title,
|
||||
Workspace: request.Workspace,
|
||||
Description: request.Description,
|
||||
}
|
||||
if err = models.DBService.Model(&models.MgtApplication{}).Create(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("应用创建成功: ID=%d, workspace=%s", dataModel.ID, dataModel.Workspace)
|
||||
infra.Response.Success(c, types.IdResp{Id: dataModel.ID, Identity: dataModel.Identity})
|
||||
}
|
||||
89
module/base/mgt/internal/logic/application/del.go
Normal file
89
module/base/mgt/internal/logic/application/del.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Del(c *gin.Context) {
|
||||
var (
|
||||
request = types.ApplicationRequest{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("删除应用参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appId := request.ID
|
||||
var dptIds []uint
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&models.MgtDepartment{}).Where("app_id = ?", appId).Pluck("id", &dptIds).Error; err != nil {
|
||||
printer.Error("查询应用部门异常: %v", err)
|
||||
return err
|
||||
}
|
||||
if len(dptIds) > 0 {
|
||||
if err := tx.Where("dpt_id in ?", dptIds).Delete(&models.MgtLinkUserDpt{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("dpt_id in ?", dptIds).Delete(&models.MgtLinkDptRole{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("dpt_id in ?", dptIds).Delete(&models.MgtLinkDptPmn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("id in ?", dptIds).Delete(&models.MgtDepartment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Where("app_id = ?", appId).Delete(&models.MgtLinkUserApp{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("app_id = ?", appId).Delete(&models.MgtLinkRoleApp{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("app_id = ?", appId).Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("app_id = ?", appId).Delete(&models.MgtLinkRolePmn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("app_id = ?", appId).Delete(&models.MgtLinkDptPmn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("app_id = ?", appId).Delete(&models.MgtPermission{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(&models.MgtApplication{}, appId).Error; err != nil {
|
||||
printer.Error("删除应用异常: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("应用删除成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID})
|
||||
}
|
||||
51
module/base/mgt/internal/logic/application/detail.go
Normal file
51
module/base/mgt/internal/logic/application/detail.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Detail(c *gin.Context) {
|
||||
var (
|
||||
request = types.ApplicationRequest{}
|
||||
data = types.ApplicationRsp{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("应用ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DBService.Model(&models.MgtApplication{}).Where("id = ?", request.ID).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
49
module/base/mgt/internal/logic/application/fetch.go
Normal file
49
module/base/mgt/internal/logic/application/fetch.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Fetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.ApplicationRequest{}
|
||||
count int64 = 0
|
||||
data = make([]types.ApplicationRsp, 0)
|
||||
db = models.DBService.Model(&models.MgtApplication{})
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Keyword != "" {
|
||||
likeStr := "%" + request.Keyword + "%"
|
||||
db = db.Where("title like ? or code like ? ", likeStr)
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ? ", request.Status)
|
||||
}
|
||||
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
132
module/base/mgt/internal/logic/application/fetch_other.go
Normal file
132
module/base/mgt/internal/logic/application/fetch_other.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 获取应用用户列表
|
||||
func UserFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = models.MgtApplication{}
|
||||
db = models.DBService.Model(&models.MgtApplication{}).Select("id", "identity", "title")
|
||||
count int64 = 0
|
||||
)
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace == "" {
|
||||
printer.Error("Workspace不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Where("workspace = ?", request.Workspace).Preload("Users", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name", "account", "phone", "email", "avatar").Count(&count).Limit(size).Offset((page - 1) * size)
|
||||
}).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
|
||||
// 获取应用角色列表
|
||||
func RoleFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtApplication, 0)
|
||||
db = models.DBService.Model(&models.MgtApplication{}).Select("id", "identity", "title")
|
||||
count int64 = 0
|
||||
)
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace == "" {
|
||||
printer.Error("Workspace不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Where("workspace = ?", request.Workspace).Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name")
|
||||
}).Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
|
||||
// 获取应用权限列表
|
||||
func PermissionFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtApplication, 0)
|
||||
db = models.DBService.Model(&models.MgtApplication{}).Select("id", "identity", "title")
|
||||
count int64 = 0
|
||||
)
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace == "" {
|
||||
printer.Error("Workspace不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Where("workspace = ?", request.Workspace).Preload("Permissions").Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
71
module/base/mgt/internal/logic/application/modify.go
Normal file
71
module/base/mgt/internal/logic/application/modify.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Midify(c *gin.Context) {
|
||||
var (
|
||||
request = types.ApplicationRequest{}
|
||||
data = models.MgtApplication{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("更新应用参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查workspace是否已被其他应用使用
|
||||
if request.Workspace != "" {
|
||||
if err := models.DBService.Model(&models.MgtApplication{}).Where("workspace=? and id<>?", request.Workspace, request.ID).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
if data.ID != 0 {
|
||||
printer.Info("工作空间已被使用: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var dataModel = models.MgtApplication{
|
||||
Title: request.Title,
|
||||
Workspace: request.Workspace,
|
||||
Description: request.Description,
|
||||
}
|
||||
if request.Status != 0 {
|
||||
dataModel.Status = request.Status
|
||||
}
|
||||
if err := models.DBService.Model(&models.MgtApplication{}).Where("id = ?", request.ID).Updates(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("应用更新成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID, Identity: dataModel.Identity})
|
||||
}
|
||||
103
module/base/mgt/internal/logic/department/create.go
Normal file
103
module/base/mgt/internal/logic/department/create.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Create(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
data = models.MgtDepartment{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 创建时必填:应用维度(应用->部门)
|
||||
if request.Workspace == "" {
|
||||
printer.Error("新增部门参数异常: workspace 不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Name == "" {
|
||||
printer.Error("新增部门参数异常: 部门名称不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到应用: workspace=%s, err=%v", request.Workspace, err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// 同一应用下部门名称唯一
|
||||
if err = models.DBService.Model(&models.MgtDepartment{}).
|
||||
Where("app_id = ? and name = ?", appId, request.Name).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
printer.Info("该应用下部门已存在: workspace=%s, name=%s", request.Workspace, request.Name)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
// 若有父部门,校验父部门属于同一应用
|
||||
if request.ParentID > 0 {
|
||||
var parent models.MgtDepartment
|
||||
if err = models.DBService.Select("id", "app_id").Where("id = ?", request.ParentID).First(&parent).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if parent.AppID != appId {
|
||||
printer.Error("父部门不属于当前应用")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 新增部门(归属当前应用)
|
||||
var dataModel = models.MgtDepartment{
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Identity: utils.ULID(), Status: 1},
|
||||
AppID: appId,
|
||||
ParentID: request.ParentID,
|
||||
LeaderID: request.LeaderID,
|
||||
Name: request.Name,
|
||||
}
|
||||
if err = models.DBService.Create(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("部门创建成功: ID=%d, name=%s", dataModel.ID, dataModel.Name)
|
||||
infra.Response.Success(c, types.IdResp{Id: dataModel.ID, Identity: dataModel.Identity})
|
||||
}
|
||||
96
module/base/mgt/internal/logic/department/del.go
Normal file
96
module/base/mgt/internal/logic/department/del.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func getDepartmentIdsRecursive(db *gorm.DB, appId uint, rootDeptId uint) ([]uint, error) {
|
||||
var allDepts []models.MgtDepartment
|
||||
if err := db.Select("id", "parent_id").Where("app_id = ?", appId).Find(&allDepts).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
childrenMap := make(map[uint][]uint, len(allDepts))
|
||||
for _, dept := range allDepts {
|
||||
if dept.ParentID > 0 {
|
||||
childrenMap[dept.ParentID] = append(childrenMap[dept.ParentID], dept.ID)
|
||||
}
|
||||
}
|
||||
result := make([]uint, 0, len(allDepts))
|
||||
var collectChildren func(uint)
|
||||
collectChildren = func(deptId uint) {
|
||||
result = append(result, deptId)
|
||||
for _, childId := range childrenMap[deptId] {
|
||||
collectChildren(childId)
|
||||
}
|
||||
}
|
||||
collectChildren(rootDeptId)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func Del(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
var dept models.MgtDepartment
|
||||
if err := models.DBService.Select("id", "app_id").Where("id = ?", request.ID).First(&dept).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
allDeptIds, err := getDepartmentIdsRecursive(models.DBService, dept.AppID, request.ID)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("dpt_id in ?", allDeptIds).Delete(&models.MgtLinkUserDpt{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("dpt_id in ?", allDeptIds).Delete(&models.MgtLinkDptRole{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("dpt_id in ?", allDeptIds).Delete(&models.MgtLinkDptPmn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("id in ?", allDeptIds).Delete(&models.MgtDepartment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID})
|
||||
}
|
||||
54
module/base/mgt/internal/logic/department/detail.go
Normal file
54
module/base/mgt/internal/logic/department/detail.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Detail(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
data = models.MgtDepartment{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("部门ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DBService.Model(&models.MgtDepartment{}).
|
||||
Select("id", "identity", "name", "app_id", "parent_id", "leader_id").Preload("Leader", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name")
|
||||
}).Where("id = ?", request.ID).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
68
module/base/mgt/internal/logic/department/fetch.go
Normal file
68
module/base/mgt/internal/logic/department/fetch.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Fetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
count int64 = 0
|
||||
data = make([]models.MgtDepartment, 0)
|
||||
db = models.DBService.Model(&models.MgtDepartment{}).Select("id", "identity", "name", "app_id", "parent_id")
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 应用->部门:列表必传 workspace,只查询应用下部门
|
||||
if request.Workspace == "" {
|
||||
printer.Error("获取部门列表参数异常: workspace 不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到应用: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
db = db.Where("app_id = ?", appId)
|
||||
|
||||
if request.Keyword != "" {
|
||||
db = db.Where("name like ?", "%"+request.Keyword+"%")
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ? ", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
if request.ParentID != 0 {
|
||||
db = db.Where("parent_id = ?", request.ParentID)
|
||||
}
|
||||
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
105
module/base/mgt/internal/logic/department/fetch_pmn.go
Normal file
105
module/base/mgt/internal/logic/department/fetch_pmn.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func PermissionsFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtDepartment, 0)
|
||||
db = models.DBService.Model(&models.MgtDepartment{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
var appId uint
|
||||
if request.Workspace != "" {
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
var err error
|
||||
appId, err = appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("workspace not found: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
db = db.Where("app_id = ?", appId)
|
||||
}
|
||||
|
||||
if request.Workspace != "" {
|
||||
if err := db.Select("id", "identity", "name").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if len(data) == 0 {
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
deptIds := make([]uint, 0, len(data))
|
||||
for _, d := range data {
|
||||
deptIds = append(deptIds, d.ID)
|
||||
}
|
||||
var links []models.MgtLinkDptPmn
|
||||
if err := models.DBService.Where("app_id = ? and dpt_id in ?", appId, deptIds).Find(&links).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
dptToPmn := make(map[uint][]uint)
|
||||
pmnIdSet := make(map[uint]struct{})
|
||||
for _, l := range links {
|
||||
dptToPmn[l.DptId] = append(dptToPmn[l.DptId], l.PmnId)
|
||||
pmnIdSet[l.PmnId] = struct{}{}
|
||||
}
|
||||
pmnIds := make([]uint, 0, len(pmnIdSet))
|
||||
for id := range pmnIdSet {
|
||||
pmnIds = append(pmnIds, id)
|
||||
}
|
||||
var perms []models.MgtPermission
|
||||
if len(pmnIds) > 0 {
|
||||
if err := models.DBService.Select("id", "identity", "title", "title_en", "sort_key", "parent_id").
|
||||
Where("id in ?", pmnIds).Find(&perms).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
permMap := make(map[uint]models.MgtPermission)
|
||||
for _, p := range perms {
|
||||
permMap[p.ID] = p
|
||||
}
|
||||
for i := range data {
|
||||
ids := dptToPmn[data[i].ID]
|
||||
data[i].Permissions = make([]models.MgtPermission, 0, len(ids))
|
||||
for _, pid := range ids {
|
||||
if p, ok := permMap[pid]; ok {
|
||||
data[i].Permissions = append(data[i].Permissions, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
|
||||
preloadPerm := func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "title", "title_en", "sort_key", "parent_id")
|
||||
}
|
||||
if err := db.Select("id", "identity", "name").Preload("Permissions", preloadPerm).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
129
module/base/mgt/internal/logic/department/fetch_pmn_tree.go
Normal file
129
module/base/mgt/internal/logic/department/fetch_pmn_tree.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func PermissionsFetchTree(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtDepartment, 0)
|
||||
db = models.DBService.Model(&models.MgtDepartment{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
var appId uint
|
||||
if request.Workspace != "" {
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
var err error
|
||||
appId, err = appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("workspace not found: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
db = db.Where("app_id = ?", appId)
|
||||
}
|
||||
|
||||
if request.Workspace != "" {
|
||||
if err := db.Select("id", "identity", "name").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if len(data) == 0 {
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
deptIds := make([]uint, 0, len(data))
|
||||
for _, d := range data {
|
||||
deptIds = append(deptIds, d.ID)
|
||||
}
|
||||
var links []models.MgtLinkDptPmn
|
||||
if err := models.DBService.Where("app_id = ? and dpt_id in ?", appId, deptIds).Find(&links).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
dptToPmn := make(map[uint][]uint)
|
||||
pmnIdSet := make(map[uint]struct{})
|
||||
for _, l := range links {
|
||||
dptToPmn[l.DptId] = append(dptToPmn[l.DptId], l.PmnId)
|
||||
pmnIdSet[l.PmnId] = struct{}{}
|
||||
}
|
||||
pmnIds := make([]uint, 0, len(pmnIdSet))
|
||||
for id := range pmnIdSet {
|
||||
pmnIds = append(pmnIds, id)
|
||||
}
|
||||
var perms []models.MgtPermission
|
||||
if len(pmnIds) > 0 {
|
||||
if err := models.DBService.Select("id", "identity", "title", "title_en", "sort_key", "parent_id", "menu_path", "code", "component", "is_web_page", "is_new_tab", "web_url").
|
||||
Where("id in ?", pmnIds).Order("sort_key").Find(&perms).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
for i := range data {
|
||||
ids := dptToPmn[data[i].ID]
|
||||
idSet := make(map[uint]struct{})
|
||||
for _, id := range ids {
|
||||
idSet[id] = struct{}{}
|
||||
}
|
||||
data[i].Permissions = buildPermTreeFilter(perms, 0, idSet)
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
|
||||
permTreePreload := func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "title", "title_en", "sort_key", "parent_id", "menu_path", "code", "component", "is_web_page", "is_new_tab", "web_url").
|
||||
Where("parent_id = 0").Order("sort_key").
|
||||
Preload("Children", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "title", "title_en", "sort_key", "parent_id", "menu_path", "code", "component", "is_web_page", "is_new_tab", "web_url").Order("sort_key")
|
||||
})
|
||||
}
|
||||
|
||||
if err := db.Select("id", "identity", "name").Preload("Permissions", permTreePreload).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
|
||||
func buildPermTreeFilter(list []models.MgtPermission, parentId uint, idSet map[uint]struct{}) []models.MgtPermission {
|
||||
var node []models.MgtPermission
|
||||
for _, p := range list {
|
||||
if _, ok := idSet[p.ID]; !ok {
|
||||
continue
|
||||
}
|
||||
isRoot := parentId == 0
|
||||
parentInSet := false
|
||||
if p.ParentID != 0 {
|
||||
_, parentInSet = idSet[p.ParentID]
|
||||
}
|
||||
matches := (p.ParentID == parentId) || (isRoot && p.ParentID != 0 && !parentInSet)
|
||||
if !matches {
|
||||
continue
|
||||
}
|
||||
children := buildPermTreeFilter(list, p.ID, idSet)
|
||||
if len(children) > 0 {
|
||||
p.Children = children
|
||||
}
|
||||
node = append(node, p)
|
||||
}
|
||||
return node
|
||||
}
|
||||
50
module/base/mgt/internal/logic/department/fetch_tree.go
Normal file
50
module/base/mgt/internal/logic/department/fetch_tree.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func FetchTree(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
data = make([]models.MgtDepartment, 0)
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Workspace == "" {
|
||||
printer.Error("workspace is required: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("workspace not found: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Model(&models.MgtDepartment{}).
|
||||
Where("app_id = ?", appId).
|
||||
Select("id", "identity", "name", "app_id", "parent_id").
|
||||
Order("parent_id asc").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
tree := buildDeptTree(data, 0)
|
||||
infra.Response.Success(c, types.FetchResp{Data: tree})
|
||||
}
|
||||
82
module/base/mgt/internal/logic/department/list.go
Normal file
82
module/base/mgt/internal/logic/department/list.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// List 下拉用部门列表,必传 workspace;tree=true 时返回树形
|
||||
func List(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
data = make([]models.MgtDepartment, 0)
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Workspace == "" {
|
||||
printer.Error("部门列表参数异常: workspace 不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到应用: workspace=%s", request.Workspace)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
db := models.DBService.Model(&models.MgtDepartment{}).
|
||||
Where("app_id = ?", appId).
|
||||
Select("id", "identity", "name", "app_id", "parent_id")
|
||||
if request.Keyword != "" {
|
||||
db = db.Where("name LIKE ?", "%"+request.Keyword+"%")
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
|
||||
if request.Tree {
|
||||
if err := db.Order("parent_id asc").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
tree := buildDeptTree(data, 0)
|
||||
infra.Response.Success(c, types.FetchResp{Data: tree})
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Order("parent_id asc").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data})
|
||||
}
|
||||
|
||||
// buildDeptTree 将扁平部门列表按 parent_id 建树,parentId 为根节点父ID(0 表示顶层)
|
||||
func buildDeptTree(list []models.MgtDepartment, parentId uint) []models.MgtDepartment {
|
||||
var node []models.MgtDepartment
|
||||
for _, d := range list {
|
||||
if d.ParentID != parentId {
|
||||
continue
|
||||
}
|
||||
children := buildDeptTree(list, d.ID)
|
||||
if len(children) > 0 {
|
||||
d.Children = children
|
||||
}
|
||||
node = append(node, d)
|
||||
}
|
||||
return node
|
||||
}
|
||||
112
module/base/mgt/internal/logic/department/modify.go
Normal file
112
module/base/mgt/internal/logic/department/modify.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Modify(c *gin.Context) {
|
||||
var (
|
||||
request = types.DptReq{}
|
||||
data = models.MgtDepartment{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DBService.Select("id", "app_id", "identity").Where("id = ?", request.ID).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
appId := data.AppID
|
||||
|
||||
if request.ParentID > 0 {
|
||||
if request.ParentID == request.ID {
|
||||
printer.Error("self-reference is not allowed: id=%d", request.ID)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
descendantIds, err := getDepartmentIdsRecursive(models.DBService, appId, request.ID)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
for _, id := range descendantIds {
|
||||
if id == request.ParentID {
|
||||
printer.Error("self-reference is not allowed: parent_id=%d", request.ParentID)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if request.Name != "" {
|
||||
var exist models.MgtDepartment
|
||||
if err = models.DBService.Model(&models.MgtDepartment{}).
|
||||
Where("app_id = ? and name = ? and id <> ?", appId, request.Name, request.ID).First(&exist).Error; err == nil {
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if request.ParentID > 0 {
|
||||
var parent models.MgtDepartment
|
||||
if err = models.DBService.Select("id", "app_id").Where("id = ?", request.ParentID).First(&parent).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if parent.AppID != appId {
|
||||
printer.Error("parent department not found: parent_id=%d, app_id=%d", request.ParentID, appId)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var dataModel = models.MgtDepartment{
|
||||
Name: request.Name,
|
||||
ParentID: request.ParentID,
|
||||
LeaderID: request.LeaderID,
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Status: request.Status},
|
||||
}
|
||||
if err := models.DBService.Model(&models.MgtDepartment{}).Where("id = ?", request.ID).Updates(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("department modified: id=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID, Identity: data.Identity})
|
||||
}
|
||||
199
module/base/mgt/internal/logic/department/set_pmn.go
Normal file
199
module/base/mgt/internal/logic/department/set_pmn.go
Normal file
@@ -0,0 +1,199 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// SetPmn 给部门设置权限(应用->部门->权限,校验部门所属应用与 workspace 一致)
|
||||
func SetPmn(c *gin.Context) {
|
||||
var (
|
||||
request = types.AddPmnRequest{}
|
||||
pmnData = make([]models.MgtLinkDptPmn, 0)
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到应用: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
var dpt models.MgtDepartment
|
||||
if err := models.DBService.Select("id", "app_id").Where("id = ?", request.Id).First(&dpt).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if dpt.AppID != appId {
|
||||
printer.Error("部门不属于当前应用: dpt_id=%d", request.Id)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnData = append(pmnData, models.MgtLinkDptPmn{AppId: appId, PmnId: v, DptId: request.Id})
|
||||
}
|
||||
|
||||
if err := models.DBService.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "dpt_id"}, {Name: "app_id"}, {Name: "pmn_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"dpt_id", "app_id", "pmn_id"}),
|
||||
}).Create(&pmnData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("部门权限设置成功: dptId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// ModifyPmn 按应用维度覆盖部门权限
|
||||
func ModifyPmn(c *gin.Context) {
|
||||
var (
|
||||
request = types.AddPmnRequest{}
|
||||
pmnData = make([]models.MgtLinkDptPmn, 0)
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到应用: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
var dpt models.MgtDepartment
|
||||
if err := models.DBService.Select("id", "app_id").Where("id = ?", request.Id).First(&dpt).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if dpt.AppID != appId {
|
||||
printer.Error("部门不属于当前应用: dpt_id=%d", request.Id)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnData = append(pmnData, models.MgtLinkDptPmn{AppId: appId, PmnId: v, DptId: request.Id})
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("dpt_id = ? and app_id = ?", request.Id, appId).Delete(&models.MgtLinkDptPmn{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if len(pmnData) > 0 {
|
||||
if err := tx.Create(&pmnData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("部门权限修改成功: dptId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// DelPmn 移除部门权限
|
||||
func DelPmn(c *gin.Context) {
|
||||
var request = types.AddPmnRequest{}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if len(request.List) == 0 {
|
||||
printer.Error("移除部门权限参数异常: list 不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到应用: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
var dpt models.MgtDepartment
|
||||
if err := models.DBService.Select("id", "app_id").Where("id = ?", request.Id).First(&dpt).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if dpt.AppID != appId {
|
||||
printer.Error("部门不属于当前应用: dpt_id=%d", request.Id)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
pmnIds := make([]uint, 0, len(request.List))
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnIds = append(pmnIds, v)
|
||||
}
|
||||
if err := models.DBService.Where("dpt_id = ? AND app_id = ? AND pmn_id in ?", request.Id, appId, pmnIds).
|
||||
Delete(&models.MgtLinkDptPmn{}).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("部门权限删除成功: dptId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
107
module/base/mgt/internal/logic/department/user.go
Normal file
107
module/base/mgt/internal/logic/department/user.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package department
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// SetUser 将用户移入部门(可批量)
|
||||
func SetUser(c *gin.Context) {
|
||||
var request types.DptUserRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
var dpt models.MgtDepartment
|
||||
if err := models.DBService.Select("id").Where("id = ?", request.DptId).First(&dpt).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
list := make([]models.MgtLinkUserDpt, 0, len(request.UserIds))
|
||||
for _, uid := range request.UserIds {
|
||||
list = append(list, models.MgtLinkUserDpt{UserId: uid, DptId: request.DptId})
|
||||
}
|
||||
if err := models.DBService.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "user_id"}, {Name: "dpt_id"}},
|
||||
DoNothing: true,
|
||||
}).Create(&list).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户移入部门成功: dptId=%d, count=%d", request.DptId, len(request.UserIds))
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// DelUser 将用户移出部门(可批量)
|
||||
func DelUser(c *gin.Context) {
|
||||
var request types.DptUserRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
result := models.DBService.Where("dpt_id = ? and user_id in ?", request.DptId, request.UserIds).
|
||||
Delete(&models.MgtLinkUserDpt{})
|
||||
if result.Error != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户移出部门成功: dptId=%d, count=%d", request.DptId, result.RowsAffected)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// UserFetch 获取部门下用户列表
|
||||
func UserFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtDepartment, 0)
|
||||
db = models.DBService.Model(&models.MgtDepartment{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.ID == 0 {
|
||||
printer.Error("获取部门用户参数异常: 部门ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
db = db.Where("id = ?", request.ID)
|
||||
|
||||
if err := db.Select("id", "identity", "name").Preload("Users", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name")
|
||||
}).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
35
module/base/mgt/internal/logic/hello/ping.go
Normal file
35
module/base/mgt/internal/logic/hello/ping.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package hello
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Ping
|
||||
func Ping(ctx *gin.Context) {
|
||||
|
||||
// file, err := ctx.FormFile("fileContent")
|
||||
// if err != nil {
|
||||
// fmt.Println("err", err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// ctx.SaveUploadedFile(file, "./tmp/"+file.Filename)
|
||||
// ctx.JSON(200, gin.H{
|
||||
// "msg": file,
|
||||
// })
|
||||
ctx.JSON(200, gin.H{"message": "Pong"})
|
||||
}
|
||||
func SessionDemo(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
session.Set("key", "12345")
|
||||
if err := session.Save(); err != nil {
|
||||
ctx.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
value := session.Get("key")
|
||||
fmt.Println("session value: ", value)
|
||||
ctx.JSON(200, gin.H{"message": "Pong"})
|
||||
}
|
||||
86
module/base/mgt/internal/logic/permission/create.go
Normal file
86
module/base/mgt/internal/logic/permission/create.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
coreutils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Create(c *gin.Context) {
|
||||
var (
|
||||
request = types.PermissionRequest{}
|
||||
data = models.MgtPermission{}
|
||||
app models.MgtApplication
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
app = models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := app.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("??appId??: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
db := models.DBService.Model(&models.MgtPermission{})
|
||||
if err = db.Where("code = ? AND app_id = ?", request.Code, appId).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
var deletedData models.MgtPermission
|
||||
if err = models.DBService.Unscoped().Where("code = ? AND app_id = ?", request.Code, appId).First(&deletedData).Error; err == nil {
|
||||
if err = models.DBService.Unscoped().Delete(&deletedData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
var dataModel = models.MgtPermission{
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Identity: coreutils.UUID(), Status: 1},
|
||||
Code: request.Code,
|
||||
Title: request.Title,
|
||||
TitleEn: request.TitleEn,
|
||||
Description: request.Description,
|
||||
Appid: appId,
|
||||
ParentID: request.ParentID,
|
||||
MenuPath: request.MenuPath,
|
||||
MenuIcon: request.MenuIcon,
|
||||
Type: request.Type,
|
||||
Component: request.Component,
|
||||
IsWebPage: request.IsWebPage,
|
||||
IsNewTab: request.IsNewTab,
|
||||
IsFull: request.IsFull,
|
||||
HideMenu: request.HideMenu,
|
||||
WebUrl: request.WebUrl,
|
||||
}
|
||||
if err = models.DBService.Model(&models.MgtPermission{}).Create(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.IdResp{Id: dataModel.ID, Identity: dataModel.Identity})
|
||||
}
|
||||
70
module/base/mgt/internal/logic/permission/del.go
Normal file
70
module/base/mgt/internal/logic/permission/del.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Del(c *gin.Context) {
|
||||
var request = types.PermissionRequest{}
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("删除权限参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 删除权限时,同时删除关联数据
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
// 删除权限
|
||||
if err = tx.Delete(&models.MgtPermission{}, request.ID).Error; err != nil {
|
||||
printer.Error("删除权限异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除用户权限关联
|
||||
if err = tx.Where("pmn_id = ?", request.ID).Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
printer.Error("删除用户权限关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除角色权限关联
|
||||
if err = tx.Where("pmn_id = ?", request.ID).Delete(&models.MgtLinkRolePmn{}).Error; err != nil {
|
||||
printer.Error("删除角色权限关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除部门权限关联
|
||||
if err = tx.Where("pmn_id = ?", request.ID).Delete(&models.MgtLinkDptPmn{}).Error; err != nil {
|
||||
printer.Error("删除部门权限关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("权限删除成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID})
|
||||
}
|
||||
51
module/base/mgt/internal/logic/permission/detail.go
Normal file
51
module/base/mgt/internal/logic/permission/detail.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Detail(c *gin.Context) {
|
||||
var (
|
||||
request = types.PermissionRequest{}
|
||||
data = types.PermissionRsp{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DBService.Model(&models.MgtPermission{}).Where("id = ?", request.ID).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
68
module/base/mgt/internal/logic/permission/fetch.go
Normal file
68
module/base/mgt/internal/logic/permission/fetch.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Fetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.PermissionRequest{}
|
||||
count int64 = 0
|
||||
data = make([]types.PermissionRsp, 0)
|
||||
db = models.DBService.Model(&models.MgtPermission{})
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Keyword != "" {
|
||||
likeStr := "%" + request.Keyword + "%"
|
||||
db = db.Where("title like ? or code like ? ", likeStr)
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ? ", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
if request.Workspace != "" {
|
||||
app := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := app.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("查询应用信息异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
db = db.Where("app_id = ?", appId)
|
||||
}
|
||||
// 按 sort_key 排序
|
||||
if request.OrderDesc {
|
||||
db = db.Order("sort_key desc")
|
||||
} else {
|
||||
db = db.Order("sort_key asc")
|
||||
}
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
93
module/base/mgt/internal/logic/permission/fetch_other.go
Normal file
93
module/base/mgt/internal/logic/permission/fetch_other.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 获取权限用户列表
|
||||
func UserFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtPermission, 0)
|
||||
db = models.DBService.Model(&models.MgtPermission{}).Select("id", "identity", "title")
|
||||
count int64 = 0
|
||||
)
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace == "" {
|
||||
printer.Error("Workspace不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Preload("Users", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name")
|
||||
}).Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
|
||||
// 获取权限角色列表
|
||||
func RoleFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtPermission, 0)
|
||||
db = models.DBService.Model(&models.MgtPermission{}).Select("id", "identity", "title")
|
||||
count int64 = 0
|
||||
)
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace == "" {
|
||||
printer.Error("Workspace不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Preload("Roles").Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
146
module/base/mgt/internal/logic/permission/modify.go
Normal file
146
module/base/mgt/internal/logic/permission/modify.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Midify(c *gin.Context) {
|
||||
var (
|
||||
request = types.PermissionRequest{}
|
||||
data = models.MgtPermission{}
|
||||
app models.MgtApplication
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("更新权限参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace != "" {
|
||||
app = models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := app.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("获取appId异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Code != "" {
|
||||
data = models.MgtPermission{}
|
||||
if err := models.DBService.Model(&models.MgtPermission{}).Where("code = ? AND app_id = ? AND id <> ?", request.Code, appId, request.ID).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
if data.ID != 0 {
|
||||
printer.Info("权限code已存在: code=%s", request.Code)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var dataModel = models.MgtPermission{
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Status: request.Status},
|
||||
Code: request.Code,
|
||||
Title: request.Title,
|
||||
Appid: appId,
|
||||
ParentID: request.ParentID,
|
||||
MenuPath: request.MenuPath,
|
||||
MenuIcon: request.MenuIcon,
|
||||
Type: request.Type,
|
||||
Component: request.Component,
|
||||
Description: request.Description,
|
||||
IsWebPage: request.IsWebPage,
|
||||
IsNewTab: request.IsNewTab,
|
||||
IsFull: request.IsFull,
|
||||
HideMenu: request.HideMenu,
|
||||
WebUrl: request.WebUrl,
|
||||
}
|
||||
|
||||
updateFields := []string{"status", "code", "title", "app_id", "parent_id", "menu_path", "menu_icon", "type", "component", "description", "is_web_page", "is_new_tab", "is_full", "hide_menu", "web_url"}
|
||||
if err := models.DBService.Model(&models.MgtPermission{}).Where("id = ?", request.ID).Select(updateFields).Updates(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("权限更新成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID, Identity: dataModel.Identity})
|
||||
return
|
||||
}
|
||||
|
||||
var existing models.MgtPermission
|
||||
if err := models.DBService.Select("app_id").Where("id = ?", request.ID).First(&existing).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Code != "" {
|
||||
data = models.MgtPermission{}
|
||||
if err := models.DBService.Model(&models.MgtPermission{}).
|
||||
Where("code = ? AND app_id = ? AND id <> ?", request.Code, existing.Appid, request.ID).
|
||||
First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
if data.ID != 0 {
|
||||
printer.Info("权限code已存在: code=%s", request.Code)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var dataModel = models.MgtPermission{
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Status: request.Status},
|
||||
Code: request.Code,
|
||||
Title: request.Title,
|
||||
ParentID: request.ParentID,
|
||||
MenuPath: request.MenuPath,
|
||||
MenuIcon: request.MenuIcon,
|
||||
Type: request.Type,
|
||||
Component: request.Component,
|
||||
Description: request.Description,
|
||||
IsWebPage: request.IsWebPage,
|
||||
IsNewTab: request.IsNewTab,
|
||||
IsFull: request.IsFull,
|
||||
HideMenu: request.HideMenu,
|
||||
WebUrl: request.WebUrl,
|
||||
}
|
||||
|
||||
updateFields := []string{"status", "code", "title", "parent_id", "menu_path", "menu_icon", "type", "component", "description", "is_web_page", "is_new_tab", "is_full", "hide_menu", "web_url"}
|
||||
if err := models.DBService.Model(&models.MgtPermission{}).Where("id = ?", request.ID).Select(updateFields).Updates(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("权限更新成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID, Identity: dataModel.Identity})
|
||||
}
|
||||
55
module/base/mgt/internal/logic/permission/sort.go
Normal file
55
module/base/mgt/internal/logic/permission/sort.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package permission
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func Sort(c *gin.Context) {
|
||||
var (
|
||||
request = make([]types.SortPmnRequest, 0)
|
||||
data = make([]models.MgtPermission, 0)
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if len(request) == 0 {
|
||||
printer.Error("排序参数不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range request {
|
||||
if err := libs.ValidateStruct(&v); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, v := range request {
|
||||
data = append(data, models.MgtPermission{
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{ID: v.PmnId},
|
||||
SortKey: int8(v.SortKey),
|
||||
})
|
||||
}
|
||||
if err := models.DBService.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"sort_key"}),
|
||||
}).Create(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("权限排序成功: 排序了 %d 个权限", len(request))
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
103
module/base/mgt/internal/logic/pub/forget.go
Normal file
103
module/base/mgt/internal/logic/pub/forget.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package pub
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/impl"
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreutils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ForgetPwdBySms 忘记密码-通过短信更改
|
||||
func ForgetPwdBySms(c *gin.Context) {
|
||||
request := types.ForgetPwdRequest{}
|
||||
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Code == "" {
|
||||
printer.Error("验证码不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
var data models.MgtUser
|
||||
if err := models.DBService.Model(&models.MgtUser{}).Where("account = ?", request.Account).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if data.Phone != request.Phone {
|
||||
printer.Error("账号与手机号不匹配: account=%s, phone=%s", request.Account, request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
smsKey := types.KeyPrefix + request.Phone
|
||||
storedCode, err := impl.RedisService.Client.Get(impl.RedisService.Ctx, smsKey).Result()
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
printer.Error("验证码已过期或不存在: phone=%s", request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
printer.Error("读取验证码异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
if storedCode != request.Code {
|
||||
printer.Error("验证码不正确: phone=%s", request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if data.Salt == "" {
|
||||
data.Salt = coreutils.UUID()
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(request.Password+data.Salt), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
printer.Error("密码加密异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Model(&models.MgtUser{}).Where("id = ?", data.ID).Updates(map[string]interface{}{
|
||||
"password": string(hashedPassword),
|
||||
"salt": data.Salt,
|
||||
}).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if err := impl.RedisService.Client.Del(impl.RedisService.Ctx, smsKey).Err(); err != nil {
|
||||
printer.Error("清除验证码缓存异常: %v", err)
|
||||
}
|
||||
|
||||
printer.Info("密码重置成功: account=%s, phone=%s", request.Account, request.Phone)
|
||||
infra.Response.Success(c, "密码重置成功")
|
||||
}
|
||||
|
||||
// ForgetPwdByPwd 忘记密码-通过旧密码更改
|
||||
func ForgetPwdByPwd(c *gin.Context) {
|
||||
}
|
||||
158
module/base/mgt/internal/logic/pub/login.go
Normal file
158
module/base/mgt/internal/logic/pub/login.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package pub
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/impl"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/crypto/token"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Login 登录
|
||||
// @Summary 登录
|
||||
// @Description 登录
|
||||
// @Tags 登录
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param role body types.LoginRequest true "登录请求"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} types.LoginResp "新增成功,返回token"
|
||||
// @Router /login [post]
|
||||
func Login(c *gin.Context) {
|
||||
var (
|
||||
request types.LoginRequest
|
||||
resp = types.LoginResp{}
|
||||
user = models.MgtUser{}
|
||||
extend = map[string]string{}
|
||||
err error
|
||||
account string
|
||||
pwd string
|
||||
)
|
||||
err = c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Account != "" && request.Password != "" {
|
||||
account = request.Account
|
||||
pwd = request.Password
|
||||
} else if request.AppId != "" && request.AppKey != "" {
|
||||
account = request.AppId
|
||||
pwd = request.AppKey
|
||||
} else {
|
||||
printer.Error("登录参数异常: 账号密码或AppId/AppKey必须提供")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
if err = models.DBService.Model(&models.MgtUser{}).Where("account=?", account).First(&user).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
resp = types.LoginResp{Phone: user.Phone, Email: user.Email, Name: user.Name, UserId: user.ID, Account: user.Account, Avatar: user.Avatar, Identity: user.Identity}
|
||||
// 检测Password与Status
|
||||
if request.AppKey != "" {
|
||||
err = checkAppKeyAndStatus(user.Password, pwd, int16(user.Status))
|
||||
} else {
|
||||
err = checkPwdAndStatus(user.Password, pwd, user.Salt, int16(user.Status))
|
||||
}
|
||||
if err != nil {
|
||||
printer.Error("检测Password与Status异常: %v", err)
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
extend["id"] = strconv.Itoa(int(user.ID))
|
||||
extend["Identity"] = user.Identity
|
||||
extend["status"] = strconv.Itoa(int(user.Status))
|
||||
extend["name"] = user.Name
|
||||
|
||||
// 获取token
|
||||
resp.Token, err = token.New(env.Runtime.JwtSecretKey).GenerateJwt(uint(user.ID), user.Identity, c.ClientIP(), "", nil, extend)
|
||||
if err != nil {
|
||||
printer.Error("获取token异常: %v", err)
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = models.UpdateLastLoginDate(uint(user.ID))
|
||||
if err != nil {
|
||||
printer.Error("更新最后登录时间异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户登录成功: account=%s, userId=%d", account, user.ID)
|
||||
infra.Response.Success(c, resp)
|
||||
}
|
||||
|
||||
func SaveToken(id int64, role, token string) error {
|
||||
tokenKey := fmt.Sprintf("%d-%s-%s", uint(id), role, "token")
|
||||
status := impl.RedisService.Client.Set(impl.RedisService.Ctx, tokenKey, token, 0)
|
||||
if status.Val() != "OK" {
|
||||
printer.Error("保存token失败: %v", errcode.ErrTokenAuthTokenChanged)
|
||||
return errcode.ErrTokenAuthTokenChanged
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPwdAndStatus(userPwd, inPwd, salt string, stat int16) error {
|
||||
// 账号是否禁用
|
||||
if stat == vars.DisabledStatus {
|
||||
printer.Error("检查账号状态异常: 账号已禁用")
|
||||
return errcode.ErrUnavailable
|
||||
}
|
||||
|
||||
err := bcrypt.CompareHashAndPassword([]byte(userPwd), []byte(inPwd+salt))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 如果bcrypt失败,尝试MD5验证(向后兼容旧用户)
|
||||
isBcrypt := len(userPwd) > 4 && (userPwd[0:4] == "$2a$" || userPwd[0:4] == "$2b$" || userPwd[0:4] == "$2y$")
|
||||
if isBcrypt {
|
||||
printer.Error("密码验证失败: bcrypt验证失败")
|
||||
return errcode.ErrPassword
|
||||
}
|
||||
|
||||
hash := md5.Sum([]byte(inPwd + salt))
|
||||
md5Hash := hex.EncodeToString(hash[:])
|
||||
if userPwd == md5Hash {
|
||||
return nil
|
||||
}
|
||||
|
||||
printer.Error("密码验证失败: 所有验证方式均失败")
|
||||
return errcode.ErrPassword
|
||||
}
|
||||
|
||||
func checkAppKeyAndStatus(userPwd, pwd string, stat int16) error {
|
||||
if userPwd != pwd {
|
||||
printer.Error("检查密码异常: 密码不匹配")
|
||||
return errcode.ErrPassword
|
||||
}
|
||||
|
||||
if stat == vars.DisabledStatus {
|
||||
printer.Error("检查账号状态异常: 账号已禁用")
|
||||
return errcode.ErrUnavailable
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
35
module/base/mgt/internal/logic/pub/refresh.go
Normal file
35
module/base/mgt/internal/logic/pub/refresh.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package pub
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/crypto/token"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Refresh 刷新token
|
||||
// @Summary 刷新token
|
||||
// @Description 刷新token
|
||||
// @Tags 刷新token
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} coreTypes.LoginResp "刷新成功,返回token"
|
||||
// @Router /pub/refresh [post]
|
||||
func Refresh(c *gin.Context) {
|
||||
claims, err := service.ParseMetaCtx(c, nil)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
// 将 ExpiresAt 转换为 time.Time 类型
|
||||
token, err := token.New(env.Runtime.JwtSecretKey).GenerateJwt(claims.ID, claims.Identity, claims.Client, claims.Role, nil, claims.Extend)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenGenerate)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, map[string]string{"token": token})
|
||||
}
|
||||
71
module/base/mgt/internal/logic/role/create.go
Normal file
71
module/base/mgt/internal/logic/role/create.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
coreutils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Create(c *gin.Context) {
|
||||
var (
|
||||
request = types.RoleReq{}
|
||||
data = models.MgtRole{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Name == "" {
|
||||
printer.Error("role name is required: name=%s", request.Name)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
db := models.DBService.Model(&models.MgtRole{})
|
||||
if err = db.Where("name = ? ", request.Name).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
var deletedData models.MgtRole
|
||||
if err = models.DBService.Unscoped().Where("name = ?", request.Name).First(&deletedData).Error; err == nil {
|
||||
if err = models.DBService.Unscoped().Delete(&deletedData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
printer.Info("role deleted: id=%d, name=%s", deletedData.ID, deletedData.Name)
|
||||
}
|
||||
} else {
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
var dataModel = models.MgtRole{
|
||||
Description: request.Description,
|
||||
Name: request.Name,
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Identity: coreutils.UUID(), Status: 1},
|
||||
}
|
||||
if err = models.DBService.Model(&models.MgtRole{}).Create(&dataModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.IdResp{Id: dataModel.ID, Identity: dataModel.Identity})
|
||||
}
|
||||
94
module/base/mgt/internal/logic/role/del.go
Normal file
94
module/base/mgt/internal/logic/role/del.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Del(c *gin.Context) {
|
||||
var (
|
||||
request = types.RoleReq{}
|
||||
pmnId = []uint{}
|
||||
userIds = []uint{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("删除角色参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Model(&models.MgtLinkRolePmn{}).Where("role_id=?", request.ID).Pluck("pmn_id", &pmnId).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if len(pmnId) > 0 {
|
||||
if err := models.DBService.Model(&models.MgtLinkUserRole{}).
|
||||
Where("role_id = ?", request.ID).
|
||||
Pluck("user_id", &userIds).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if len(pmnId) > 0 && len(userIds) > 0 {
|
||||
if err := tx.Where("user_id in ? and pmn_id in ?", userIds, pmnId).
|
||||
Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
printer.Error("删除用户对应角色权限异常: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Delete(&models.MgtRole{}, request.ID).Error; err != nil {
|
||||
printer.Error("删除角色异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Where("role_id = ?", request.ID).Delete(&models.MgtLinkRolePmn{}).Error; err != nil {
|
||||
printer.Error("删除角色权限关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Where("role_id = ?", request.ID).Delete(&models.MgtLinkUserRole{}).Error; err != nil {
|
||||
printer.Error("删除角色用户关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Where("role_id = ?", request.ID).Delete(&models.MgtLinkRoleApp{}).Error; err != nil {
|
||||
printer.Error("删除角色应用关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Where("role_id = ?", request.ID).Delete(&models.MgtLinkDptRole{}).Error; err != nil {
|
||||
printer.Error("删除部门角色关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("角色删除成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID})
|
||||
}
|
||||
51
module/base/mgt/internal/logic/role/detail.go
Normal file
51
module/base/mgt/internal/logic/role/detail.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Detail(c *gin.Context) {
|
||||
var (
|
||||
request = types.RoleReq{}
|
||||
data = models.MgtRole{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("角色ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DBService.Model(&models.MgtRole{}).Select("id", "identity", "name", "description").Where("id = ?", request.ID).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
51
module/base/mgt/internal/logic/role/fetch.go
Normal file
51
module/base/mgt/internal/logic/role/fetch.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Fetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.RoleReq{}
|
||||
count int64 = 0
|
||||
data = make([]models.MgtRole, 0)
|
||||
db = models.DBService.Model(&models.MgtRole{}).Select("id", "identity", "name", "description")
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Keyword != "" {
|
||||
db = db.Where("name like ?", "%"+request.Keyword+"%")
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ? ", request.Status)
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
133
module/base/mgt/internal/logic/role/fetch_other.go
Normal file
133
module/base/mgt/internal/logic/role/fetch_other.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func PermissionsFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtRole, 0)
|
||||
db = models.DBService.Model(&models.MgtRole{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
|
||||
if err := db.Select("id", "identity", "name").Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "title", "title_en", "sort_key", "parent_id")
|
||||
}).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
|
||||
func PermissionsFetchTree(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtRole, 0)
|
||||
db = models.DBService.Model(&models.MgtRole{})
|
||||
)
|
||||
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
|
||||
if err := db.Select("id", "identity", "name").Preload("Application", func(db *gorm.DB) *gorm.DB {
|
||||
db = db.Select("id", "identity", "title")
|
||||
if request.Workspace != "" {
|
||||
db = db.Where("workspace = ?", request.Workspace)
|
||||
}
|
||||
return db.Preload("RolesPmn", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "title", "title_en", "sort_key", "parent_id", "menu_path", "code", "component", "is_web_page", "is_new_tab", "web_url").
|
||||
Where("parent_id=0").Order("sort_key").
|
||||
Preload("Children", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "title", "title_en", "sort_key", "parent_id", "menu_path", "code", "component", "is_web_page", "is_new_tab", "web_url").Order("sort_key")
|
||||
})
|
||||
})
|
||||
}).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
|
||||
func ApplicationsFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtRole, 0)
|
||||
db = models.DBService.Model(&models.MgtRole{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
|
||||
if err := db.Select("id", "identity", "name").Preload("Application").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
|
||||
func UserFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtRole, 0)
|
||||
db = models.DBService.Model(&models.MgtRole{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
if request.ID != 0 {
|
||||
db = db.Where("id = ?", request.ID)
|
||||
}
|
||||
if err := db.Select("id", "identity", "name").Preload("Users", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name")
|
||||
}).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
67
module/base/mgt/internal/logic/role/modify.go
Normal file
67
module/base/mgt/internal/logic/role/modify.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Midify(c *gin.Context) {
|
||||
var (
|
||||
request = types.RoleReq{}
|
||||
data = models.MgtRole{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("更新角色参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Name != "" {
|
||||
db := models.DBService.Model(&models.MgtRole{})
|
||||
if err = db.Where("name = ? and id<> ?", request.Name, request.ID).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
if data.ID != 0 {
|
||||
printer.Info("角色名称已存在: name=%s", request.Name)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var roleModel = models.MgtRole{
|
||||
Name: request.Name,
|
||||
Description: request.Description,
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Status: request.Status},
|
||||
}
|
||||
if err := models.DBService.Model(&models.MgtRole{}).Where("id = ?", request.ID).Updates(&roleModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("角色更新成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID, Identity: roleModel.Identity})
|
||||
}
|
||||
170
module/base/mgt/internal/logic/role/set.go
Normal file
170
module/base/mgt/internal/logic/role/set.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package role
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// SetPmn 给角色设置权限
|
||||
func SetPmn(c *gin.Context) {
|
||||
var (
|
||||
request = types.AddPmnRequest{}
|
||||
pmnData = make([]models.MgtLinkRolePmn, 0)
|
||||
Appdta = models.MgtLinkRoleApp{}
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到appid: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnData = append(pmnData, models.MgtLinkRolePmn{AppId: appId, PmnId: v, RoleId: request.Id})
|
||||
Appdta = models.MgtLinkRoleApp{AppId: appId, RoleId: request.Id}
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "pmn_id"}, {Name: "role_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "pmn_id", "role_id"}),
|
||||
}).Create(&pmnData).Error; err != nil {
|
||||
printer.Error("创建角色权限关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "role_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "role_id"}),
|
||||
}).Create(&Appdta).Error; err != nil {
|
||||
printer.Error("创建角色应用关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("角色权限设置成功: roleId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// ModifyPmn 给角色修改权限
|
||||
func ModifyPmn(c *gin.Context) {
|
||||
var (
|
||||
request = types.AddPmnRequest{}
|
||||
pmnData = make([]models.MgtLinkRolePmn, 0)
|
||||
Appdta = models.MgtLinkRoleApp{}
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到appid: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnData = append(pmnData, models.MgtLinkRolePmn{AppId: appId, PmnId: v, RoleId: request.Id})
|
||||
Appdta = models.MgtLinkRoleApp{AppId: appId, RoleId: request.Id}
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("app_id = ? and role_id = ?", appId, request.Id).Delete(&models.MgtLinkRolePmn{}).Error; err != nil {
|
||||
printer.Error("删除角色权限关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := tx.Where("app_id = ? and role_id = ?", appId, request.Id).Delete(&models.MgtLinkRoleApp{}).Error; err != nil {
|
||||
printer.Error("删除角色应用关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&pmnData).Error; err != nil {
|
||||
printer.Error("创建角色权限关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&Appdta).Error; err != nil {
|
||||
printer.Error("创建角色应用关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("角色权限修改成功: roleId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// DelPmn 角色权限移除
|
||||
func DelPmn(c *gin.Context) {
|
||||
var request = types.AddPmnRequest{}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到appid: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
pmnIds := make([]uint, 0, len(request.List))
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnIds = append(pmnIds, v)
|
||||
}
|
||||
if err := models.DBService.Where("app_id = ? AND role_id = ? AND pmn_id in ?", appId, request.Id, pmnIds).
|
||||
Delete(&models.MgtLinkRolePmn{}).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("角色权限删除成功: roleId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
14
module/base/mgt/internal/logic/tool/tool.go
Normal file
14
module/base/mgt/internal/logic/tool/tool.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package tool
|
||||
|
||||
import "bsm/full/module/base/mgt/internal/types"
|
||||
|
||||
func GetSizeAndPage(page, size int) (int, int) {
|
||||
if page <= 0 {
|
||||
page = types.DefaultPage
|
||||
}
|
||||
|
||||
if size <= 0 {
|
||||
size = types.DefaultSize
|
||||
}
|
||||
return page, size
|
||||
}
|
||||
124
module/base/mgt/internal/logic/user/create.go
Normal file
124
module/base/mgt/internal/logic/user/create.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/middleware"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
coreutils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Create(c *gin.Context) {
|
||||
var (
|
||||
request = types.UserRequest{}
|
||||
data = models.MgtUser{}
|
||||
linkData = models.MgtApplication{}
|
||||
)
|
||||
_, err := middleware.ParseAuth(c)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenAuthNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
err = c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Account == "" || request.Phone == "" || request.PassWord == "" {
|
||||
printer.Error("account, phone and password are required: account=%s, phone=%s", request.Account, request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
db := models.DBService.Model(&models.MgtUser{})
|
||||
if err = db.Where("phone = ? or account = ?", request.Phone, request.Account).First(&data).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
var deletedData models.MgtUser
|
||||
if err = models.DBService.Unscoped().Where("phone = ?", request.Phone).First(&deletedData).Error; err == nil {
|
||||
if err = models.DBService.Unscoped().Delete(&deletedData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
printer.Info("user deleted: id=%d, phone=%s", deletedData.ID, deletedData.Phone)
|
||||
}
|
||||
if request.Phone != request.Account {
|
||||
if err = models.DBService.Unscoped().Where("account = ?", request.Account).First(&deletedData).Error; err == nil {
|
||||
if err = models.DBService.Unscoped().Delete(&deletedData).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Workspace == "" {
|
||||
request.Workspace = "def"
|
||||
}
|
||||
if err = models.DBService.Model(&models.MgtApplication{}).Where("workspace = ?", request.Workspace).First(&linkData).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
salt := coreutils.UUID()
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(request.PassWord+salt), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
var userModel = models.MgtUser{
|
||||
Account: request.Account,
|
||||
Name: request.Name,
|
||||
Password: string(hashedPassword),
|
||||
Phone: request.Phone,
|
||||
Email: request.Email,
|
||||
Avatar: request.Avatar,
|
||||
Salt: salt,
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Identity: coreutils.UUID(), Status: 1},
|
||||
}
|
||||
|
||||
if err = models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err = tx.Model(&models.MgtUser{}).Create(&userModel).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
userLink := models.MgtLinkUserApp{
|
||||
AppId: linkData.ID,
|
||||
UserId: userModel.ID,
|
||||
}
|
||||
if err = tx.Model(&models.MgtLinkUserApp{}).Create(&userLink).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.IdResp{Id: userModel.ID, Identity: userModel.Identity})
|
||||
}
|
||||
76
module/base/mgt/internal/logic/user/del.go
Normal file
76
module/base/mgt/internal/logic/user/del.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Del(c *gin.Context) {
|
||||
var request = types.UserRequest{}
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("删除用户参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 删除用户时,同时删除关联数据
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
// 删除用户
|
||||
if err = tx.Delete(&models.MgtUser{}, request.ID).Error; err != nil {
|
||||
printer.Error("删除用户异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除用户角色关联
|
||||
if err = tx.Where("user_id = ?", request.ID).Delete(&models.MgtLinkUserRole{}).Error; err != nil {
|
||||
printer.Error("删除用户角色关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除用户应用关联
|
||||
if err = tx.Where("user_id = ?", request.ID).Delete(&models.MgtLinkUserApp{}).Error; err != nil {
|
||||
printer.Error("删除用户应用关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除用户权限关联
|
||||
if err = tx.Where("user_id = ?", request.ID).Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
printer.Error("删除用户权限关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除用户部门关联
|
||||
if err = tx.Where("user_id = ?", request.ID).Delete(&models.MgtLinkUserDpt{}).Error; err != nil {
|
||||
printer.Error("删除用户部门关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户删除成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID})
|
||||
}
|
||||
51
module/base/mgt/internal/logic/user/detail.go
Normal file
51
module/base/mgt/internal/logic/user/detail.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Detail(c *gin.Context) {
|
||||
var (
|
||||
request = types.UserRequest{}
|
||||
userData = types.UserResp{}
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("用户ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DBService.Model(&models.MgtUser{}).Where("id = ?", request.ID).First(&userData).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, userData)
|
||||
}
|
||||
49
module/base/mgt/internal/logic/user/fetch.go
Normal file
49
module/base/mgt/internal/logic/user/fetch.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/logic/tool"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Fetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.UserRequest{}
|
||||
count int64 = 0
|
||||
data = make([]types.UserResp, 0)
|
||||
db = models.DBService.Model(&models.MgtUser{})
|
||||
)
|
||||
|
||||
// 解析JSON请求
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Keyword != "" {
|
||||
likeStr := "%" + request.Keyword + "%"
|
||||
db = db.Where("name like ? or account like ? or phone like ?", likeStr, likeStr, likeStr)
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ? ", request.Status)
|
||||
}
|
||||
|
||||
page, size := tool.GetSizeAndPage(request.Page, request.Size)
|
||||
if err := db.Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, types.FetchResp{Data: data, Page: page, Size: size, Total: count})
|
||||
}
|
||||
49
module/base/mgt/internal/logic/user/fetch_app.go
Normal file
49
module/base/mgt/internal/logic/user/fetch_app.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
mgtmw "bsm/full/module/base/mgt/internal/middleware"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func ApplicationsFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtUser, 0)
|
||||
db = models.DBService.Model(&models.MgtUser{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
auth, err := middleware.ParseAuth(c)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenAuthParseFail)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
request.ID = auth.ID
|
||||
}
|
||||
if !mgtmw.EnsureSelfOrAdmin(c, request.ID) {
|
||||
return
|
||||
}
|
||||
|
||||
db = db.Where("id = ?", request.ID)
|
||||
if err := db.Select("id", "identity", "name").Preload("Application").Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
226
module/base/mgt/internal/logic/user/fetch_pmn.go
Normal file
226
module/base/mgt/internal/logic/user/fetch_pmn.go
Normal file
@@ -0,0 +1,226 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
mgtmw "bsm/full/module/base/mgt/internal/middleware"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const permissionPreloadSelect = "id,identity,title,title_en,sort_key,parent_id,menu_path,menu_icon,code,component,is_web_page,is_new_tab,is_full,hide_menu,web_url,app_id"
|
||||
|
||||
func permissionOrder(db *gorm.DB) *gorm.DB { return db.Order("sort_key asc") }
|
||||
|
||||
func pmnPreloadWithWorkspace(workspace string) func(*gorm.DB) *gorm.DB {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
db = db.Select(permissionPreloadSelect)
|
||||
if workspace != "" {
|
||||
db = db.Where("app_id = (SELECT id FROM mgt_application WHERE workspace = ?)", workspace)
|
||||
}
|
||||
return permissionOrder(db)
|
||||
}
|
||||
}
|
||||
|
||||
func mergeEffectivePermissions(u *models.MgtUser) []models.MgtPermission {
|
||||
seen := make(map[uint]struct{})
|
||||
out := make([]models.MgtPermission, 0)
|
||||
|
||||
add := func(list []models.MgtPermission) {
|
||||
for _, p := range list {
|
||||
if p.ID == 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[p.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[p.ID] = struct{}{}
|
||||
out = append(out, p)
|
||||
}
|
||||
}
|
||||
|
||||
add(u.Permissions)
|
||||
for i := range u.Roles {
|
||||
add(u.Roles[i].Permissions)
|
||||
}
|
||||
for i := range u.Departments {
|
||||
add(u.Departments[i].Permissions)
|
||||
for j := range u.Departments[i].Roles {
|
||||
add(u.Departments[i].Roles[j].Permissions)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func PermissionsFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtUser, 0)
|
||||
db = models.DBService.Model(&models.MgtUser{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
auth, err := middleware.ParseAuth(c)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenAuthParseFail)
|
||||
return
|
||||
}
|
||||
if request.ID == 0 {
|
||||
request.ID = auth.ID
|
||||
}
|
||||
if !mgtmw.EnsureSelfOrAdmin(c, request.ID) {
|
||||
return
|
||||
}
|
||||
|
||||
ws := request.Workspace
|
||||
db = db.Where("id = ?", request.ID).Select("id", "identity", "name").
|
||||
Preload("Permissions", pmnPreloadWithWorkspace(ws)).
|
||||
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name").Preload("Permissions", pmnPreloadWithWorkspace(ws))
|
||||
}).
|
||||
Preload("Departments", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name").
|
||||
Preload("Permissions", pmnPreloadWithWorkspace(ws)).
|
||||
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name").Preload("Permissions", pmnPreloadWithWorkspace(ws))
|
||||
})
|
||||
})
|
||||
|
||||
if err := db.Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if len(data) == 0 {
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
merged := mergeEffectivePermissions(&data[0])
|
||||
data[0].Permissions = merged
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
|
||||
func PermissionsFetchTree(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtUser, 0)
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
auth, err := middleware.ParseAuth(c)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenAuthParseFail)
|
||||
return
|
||||
}
|
||||
if request.ID == 0 {
|
||||
request.ID = auth.ID
|
||||
}
|
||||
if !mgtmw.EnsureSelfOrAdmin(c, request.ID) {
|
||||
return
|
||||
}
|
||||
|
||||
db := models.DBService.Model(&models.MgtUser{}).Where("id = ?", request.ID).
|
||||
Select("id", "identity", "name").
|
||||
Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
||||
}).
|
||||
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name").Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
||||
})
|
||||
}).
|
||||
Preload("Departments", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name").
|
||||
Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
||||
}).
|
||||
Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name").Preload("Permissions", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select(permissionPreloadSelect).Order("sort_key asc")
|
||||
})
|
||||
})
|
||||
})
|
||||
if err := db.Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if len(data) == 0 {
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
|
||||
merged := mergeEffectivePermissions(&data[0])
|
||||
pmnIdsByApp := make(map[uint][]uint)
|
||||
for _, p := range merged {
|
||||
if p.Appid == 0 {
|
||||
continue
|
||||
}
|
||||
pmnIdsByApp[p.Appid] = append(pmnIdsByApp[p.Appid], p.ID)
|
||||
}
|
||||
|
||||
appDb := models.DBService.Model(&models.MgtUser{}).Where("id = ?", request.ID).
|
||||
Select("id", "identity", "name")
|
||||
appDb = appDb.Preload("Application", func(db *gorm.DB) *gorm.DB {
|
||||
db = db.Select("id", "identity", "title", "workspace")
|
||||
if request.Workspace != "" {
|
||||
db = db.Where("workspace = ?", request.Workspace)
|
||||
}
|
||||
return db
|
||||
})
|
||||
var userWithApp []models.MgtUser
|
||||
if err := appDb.Find(&userWithApp).Error; err != nil || len(userWithApp) == 0 {
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
|
||||
apps := userWithApp[0].Application
|
||||
if len(apps) == 0 {
|
||||
data[0].Application = nil
|
||||
infra.Response.Success(c, data)
|
||||
return
|
||||
}
|
||||
|
||||
treeSelect := "id,identity,title,title_en,sort_key,parent_id,menu_path,menu_icon,code,component,is_web_page,is_new_tab,web_url,app_id"
|
||||
for i := range apps {
|
||||
ids := pmnIdsByApp[apps[i].ID]
|
||||
if len(ids) == 0 {
|
||||
apps[i].UsersPmn = nil
|
||||
apps[i].RolesPmn = nil
|
||||
continue
|
||||
}
|
||||
var tree []models.MgtPermission
|
||||
err := models.DBService.Model(&models.MgtPermission{}).
|
||||
Select(treeSelect).
|
||||
Where("app_id = ? AND parent_id = 0 AND id IN ?", apps[i].ID, ids).
|
||||
Order("sort_key asc").
|
||||
Preload("Children", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select(treeSelect).Where("id IN ?", ids).Order("sort_key asc")
|
||||
}).
|
||||
Find(&tree).Error
|
||||
if err != nil {
|
||||
apps[i].UsersPmn = nil
|
||||
apps[i].RolesPmn = nil
|
||||
continue
|
||||
}
|
||||
apps[i].UsersPmn = tree
|
||||
}
|
||||
|
||||
data[0].Application = apps
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
53
module/base/mgt/internal/logic/user/fetch_role.go
Normal file
53
module/base/mgt/internal/logic/user/fetch_role.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
mgtmw "bsm/full/module/base/mgt/internal/middleware"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func RoleFetch(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]models.MgtUser, 0)
|
||||
db = models.DBService.Model(&models.MgtUser{})
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
auth, err := middleware.ParseAuth(c)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenAuthParseFail)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
request.ID = auth.ID
|
||||
}
|
||||
if !mgtmw.EnsureSelfOrAdmin(c, request.ID) {
|
||||
return
|
||||
}
|
||||
|
||||
db = db.Where("id = ?", request.ID)
|
||||
|
||||
if err := db.Select("id", "identity", "name").Preload("Roles", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Select("id", "identity", "name")
|
||||
}).Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, data)
|
||||
}
|
||||
40
module/base/mgt/internal/logic/user/list.go
Normal file
40
module/base/mgt/internal/logic/user/list.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func UserList(c *gin.Context) {
|
||||
var (
|
||||
request = types.FetchBase{}
|
||||
data = make([]types.UserResp, 0)
|
||||
)
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
if request.Workspace == "" {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
db := models.DBService.Model(&models.MgtUser{}).
|
||||
Where("id IN (SELECT user_id FROM mgt_link_user_app WHERE app_id = (SELECT id FROM mgt_application WHERE workspace = ? LIMIT 1))", request.Workspace)
|
||||
if request.Keyword != "" {
|
||||
likeStr := "%" + request.Keyword + "%"
|
||||
db = db.Where("name LIKE ?", likeStr)
|
||||
}
|
||||
if request.Status != 0 {
|
||||
db = db.Where("status = ?", request.Status)
|
||||
}
|
||||
if err := db.Find(&data).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
infra.Response.Success(c, types.FetchResp{Data: data})
|
||||
}
|
||||
74
module/base/mgt/internal/logic/user/modify.go
Normal file
74
module/base/mgt/internal/logic/user/modify.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreTypes "git.apinb.com/bsm-sdk/core/types"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func Midify(c *gin.Context) {
|
||||
var (
|
||||
request = types.UserRequest{}
|
||||
user = models.MgtUser{}
|
||||
)
|
||||
|
||||
err := c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
request.PassWord = ""
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.ID == 0 {
|
||||
printer.Error("更新用户参数异常: ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Account != "" {
|
||||
if err := models.DBService.Model(&models.MgtUser{}).Where("account = ? and id <>?", request.Account, request.ID).First(&user).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
}
|
||||
if user.ID != 0 {
|
||||
printer.Info("账号已被使用: account=%s", request.Account)
|
||||
infra.Response.Error(c, errcode.ErrAlreadyExists)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var userModel = models.MgtUser{
|
||||
Name: request.Name,
|
||||
Phone: request.Phone,
|
||||
Email: request.Email,
|
||||
Avatar: request.Avatar,
|
||||
Std_IICUDS: coreTypes.Std_IICUDS{Status: request.Status},
|
||||
}
|
||||
updateFields := []string{"name", "phone", "email", "avatar", "status"}
|
||||
if request.Account != "" {
|
||||
userModel.Account = request.Account
|
||||
updateFields = append(updateFields, "account")
|
||||
}
|
||||
if err := models.DBService.Model(&models.MgtUser{}).Where("id = ?", request.ID).Select(updateFields).Updates(&userModel).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户更新成功: ID=%d", request.ID)
|
||||
infra.Response.Success(c, types.IdResp{Id: request.ID, Identity: userModel.Identity})
|
||||
}
|
||||
171
module/base/mgt/internal/logic/user/set_pmn.go
Normal file
171
module/base/mgt/internal/logic/user/set_pmn.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// SetPmn 给用户设置权限
|
||||
func SetPmn(c *gin.Context) {
|
||||
var (
|
||||
request = types.AddPmnRequest{}
|
||||
pmnData = make([]models.MgtLinkUserPmn, 0)
|
||||
Appdta = models.MgtLinkUserApp{}
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到appid: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnData = append(pmnData, models.MgtLinkUserPmn{AppId: appId, PmnId: v, UserId: request.Id})
|
||||
Appdta = models.MgtLinkUserApp{AppId: appId, UserId: request.Id}
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "pmn_id"}, {Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "pmn_id", "user_id"}),
|
||||
}).Create(&pmnData).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "user_id"}),
|
||||
}).Create(&Appdta).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户权限设置成功: userId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// ModifyPmn 给用户修改权限
|
||||
func ModifyPmn(c *gin.Context) {
|
||||
var (
|
||||
request = types.AddPmnRequest{}
|
||||
pmnData = make([]models.MgtLinkUserPmn, 0)
|
||||
Appdta = models.MgtLinkUserApp{}
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到appid: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnData = append(pmnData, models.MgtLinkUserPmn{AppId: appId, PmnId: v, UserId: request.Id})
|
||||
Appdta = models.MgtLinkUserApp{AppId: appId, UserId: request.Id}
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("app_id = ? and user_id = ?", appId, request.Id).Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
printer.Error("删除用户权限关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if len(pmnData) == 0 {
|
||||
return nil
|
||||
}
|
||||
if err := tx.Create(&pmnData).Error; err != nil {
|
||||
printer.Error("创建用户权限关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "user_id"}),
|
||||
}).Create(&Appdta).Error; err != nil {
|
||||
printer.Error("创建用户应用关联失败: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户权限修改成功: userId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// DelPmn 用户权限移除
|
||||
func DelPmn(c *gin.Context) {
|
||||
var request = types.AddPmnRequest{}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
appModel := models.MgtApplication{Workspace: request.Workspace}
|
||||
appId, err := appModel.WorkspaceToId()
|
||||
if err != nil {
|
||||
printer.Error("未获取到appid: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
pmnIds := make([]uint, 0, len(request.List))
|
||||
for _, v := range request.List {
|
||||
if v == 0 {
|
||||
printer.Error("权限ID不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
pmnIds = append(pmnIds, v)
|
||||
}
|
||||
if err := models.DBService.Where("app_id = ? AND user_id = ? AND pmn_id in ?", appId, request.Id, pmnIds).
|
||||
Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户权限删除成功: userId=%d", request.Id)
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
188
module/base/mgt/internal/logic/user/set_role.go
Normal file
188
module/base/mgt/internal/logic/user/set_role.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/mgt/internal/libs"
|
||||
"bsm/full/module/base/mgt/internal/models"
|
||||
"bsm/full/module/base/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
// SetRole 给用户设置角色
|
||||
func SetRole(c *gin.Context) {
|
||||
var (
|
||||
request = types.UserRoleRequest{}
|
||||
role = make([]models.MgtRole, 0)
|
||||
pmnData = make([]models.MgtLinkUserPmn, 0)
|
||||
roleData = make([]models.MgtLinkUserRole, 0)
|
||||
appId = make([]uint, 0)
|
||||
userApp = make([]models.MgtLinkUserApp, 0)
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Model(&models.MgtRole{}).Where("id in ?", request.RoleId).Preload("Permissions").Find(&role).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range role {
|
||||
for _, vv := range v.Permissions {
|
||||
pmnData = append(pmnData, models.MgtLinkUserPmn{
|
||||
AppId: vv.Appid,
|
||||
PmnId: vv.ID,
|
||||
UserId: request.UserId,
|
||||
})
|
||||
}
|
||||
roleData = append(roleData, models.MgtLinkUserRole{UserId: request.UserId, RoleId: v.ID})
|
||||
}
|
||||
|
||||
if err := models.DBService.Model(&models.MgtLinkRoleApp{}).Select("app_id").Where("role_id in ?", request.RoleId).Find(&appId).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
if len(appId) == 0 {
|
||||
printer.Info("角色未关联应用: roleIds=%v", request.RoleId)
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
for _, v := range appId {
|
||||
userApp = append(userApp, models.MgtLinkUserApp{UserId: request.UserId, AppId: v})
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "pmn_id"}, {Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "pmn_id", "user_id"}),
|
||||
}).Create(&pmnData).Error; err != nil {
|
||||
printer.Error("创建用户权限关系失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "app_id"}, {Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"app_id", "user_id"}),
|
||||
}).Create(&userApp).Error; err != nil {
|
||||
printer.Error("创建用户app关系失败: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "user_id"}, {Name: "role_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"user_id", "role_id"}),
|
||||
}).Create(&roleData).Error; err != nil {
|
||||
printer.Error("创建用户角色关系失败: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
|
||||
// DelRole 给用户移除角色
|
||||
func DelRole(c *gin.Context) {
|
||||
var (
|
||||
request = types.UserRoleRequest{}
|
||||
)
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Transaction(func(tx *gorm.DB) error {
|
||||
var (
|
||||
removedRolePmns []uint
|
||||
userOtherRoles []uint
|
||||
otherRolePmns []uint
|
||||
toDeletePmns []uint
|
||||
)
|
||||
|
||||
if err := tx.Model(&models.MgtLinkRolePmn{}).
|
||||
Select("pmn_id").
|
||||
Where("role_id in ?", request.RoleId).
|
||||
Find(&removedRolePmns).Error; err != nil {
|
||||
printer.Error("获取被移除角色权限异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(removedRolePmns) == 0 {
|
||||
if err := tx.Where("user_id = ? and role_id in ?", request.UserId, request.RoleId).
|
||||
Delete(&models.MgtLinkUserRole{}).Error; err != nil {
|
||||
printer.Error("删除用户角色关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := tx.Model(&models.MgtLinkUserRole{}).
|
||||
Select("role_id").
|
||||
Where("user_id = ? and role_id not in ?", request.UserId, request.RoleId).
|
||||
Find(&userOtherRoles).Error; err != nil {
|
||||
printer.Error("获取用户其他角色异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(userOtherRoles) > 0 {
|
||||
if err := tx.Model(&models.MgtLinkRolePmn{}).
|
||||
Select("pmn_id").
|
||||
Where("role_id in ?", userOtherRoles).
|
||||
Find(&otherRolePmns).Error; err != nil {
|
||||
printer.Error("获取用户其他角色权限异常: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
otherPmnSet := make(map[uint]struct{}, len(otherRolePmns))
|
||||
for _, pmnId := range otherRolePmns {
|
||||
otherPmnSet[pmnId] = struct{}{}
|
||||
}
|
||||
toDeletePmns = make([]uint, 0, len(removedRolePmns))
|
||||
for _, pmnId := range removedRolePmns {
|
||||
if _, ok := otherPmnSet[pmnId]; !ok {
|
||||
toDeletePmns = append(toDeletePmns, pmnId)
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Where("user_id = ? and role_id in ?", request.UserId, request.RoleId).
|
||||
Delete(&models.MgtLinkUserRole{}).Error; err != nil {
|
||||
printer.Error("删除用户角色关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(toDeletePmns) > 0 {
|
||||
if err := tx.Where("user_id = ? and pmn_id in ?", request.UserId, toDeletePmns).
|
||||
Delete(&models.MgtLinkUserPmn{}).Error; err != nil {
|
||||
printer.Error("删除用户权限关联异常: %v", err)
|
||||
return err
|
||||
}
|
||||
printer.Info("删除用户权限关联: userId=%d, pmnIds=%v", request.UserId, toDeletePmns)
|
||||
} else {
|
||||
printer.Info("用户权限通过其他角色或直接拥有,无需删除: userId=%d", request.UserId)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, "")
|
||||
}
|
||||
Reference in New Issue
Block a user