diff --git a/main.go b/main.go
index d7f5e87..f5fffd9 100644
--- a/main.go
+++ b/main.go
@@ -135,6 +135,12 @@ func Run() error {
if err := global.DB.AutoMigrate(&model.Resource{}); err != nil {
return err
}
+ if err := global.DB.AutoMigrate(&model.UserGroup{}); err != nil {
+ return err
+ }
+ if err := global.DB.AutoMigrate(&model.UserGroupMember{}); err != nil {
+ return err
+ }
if err := global.DB.AutoMigrate(&model.Num{}); err != nil {
return err
}
diff --git a/pkg/api/routes.go b/pkg/api/routes.go
index ec34233..b8fd34d 100644
--- a/pkg/api/routes.go
+++ b/pkg/api/routes.go
@@ -51,6 +51,17 @@ func SetupRoutes() *echo.Echo {
users.GET("/:id", UserGetEndpoint)
}
+ userGroups := e.Group("/user-groups")
+ {
+ userGroups.POST("", UserGroupCreateEndpoint)
+ userGroups.GET("/paging", UserGroupPagingEndpoint)
+ userGroups.PUT("/:id", UserGroupUpdateEndpoint)
+ userGroups.DELETE("/:id", UserGroupDeleteEndpoint)
+ userGroups.GET("/:id", UserGroupGetEndpoint)
+ userGroups.POST("/:id/members", UserGroupAddMembersEndpoint)
+ userGroups.DELETE("/:id/members/:memberId", UserGroupDelMembersEndpoint)
+ }
+
assets := e.Group("/assets", Auth)
{
assets.GET("", AssetAllEndpoint)
diff --git a/pkg/api/user-group.go b/pkg/api/user-group.go
new file mode 100644
index 0000000..24831af
--- /dev/null
+++ b/pkg/api/user-group.go
@@ -0,0 +1,114 @@
+package api
+
+import (
+ "github.com/labstack/echo/v4"
+ "next-terminal/pkg/global"
+ "next-terminal/pkg/model"
+ "next-terminal/pkg/utils"
+ "strconv"
+ "strings"
+)
+
+type UserGroup struct {
+ Name string `json:"name"`
+ Members []string `json:"members"`
+}
+
+func UserGroupCreateEndpoint(c echo.Context) error {
+ var item UserGroup
+ if err := c.Bind(&item); err != nil {
+ return err
+ }
+
+ userGroup := model.UserGroup{
+ ID: utils.UUID(),
+ Created: utils.NowJsonTime(),
+ Name: item.Name,
+ }
+
+ if err := model.CreateNewUserGroup(&userGroup, item.Members); err != nil {
+ return err
+ }
+
+ return Success(c, item)
+}
+
+func UserGroupPagingEndpoint(c echo.Context) error {
+ pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
+ pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
+ name := c.QueryParam("name")
+
+ items, total, err := model.FindPageUserGroup(pageIndex, pageSize, name)
+ if err != nil {
+ return err
+ }
+
+ return Success(c, H{
+ "total": total,
+ "items": items,
+ })
+}
+
+func UserGroupUpdateEndpoint(c echo.Context) error {
+ id := c.Param("id")
+
+ var item model.UserGroup
+ if err := c.Bind(&item); err != nil {
+ return err
+ }
+
+ model.UpdateUserGroupById(&item, id)
+
+ return Success(c, nil)
+}
+
+func UserGroupDeleteEndpoint(c echo.Context) error {
+ ids := c.Param("id")
+ split := strings.Split(ids, ",")
+ for i := range split {
+ userId := split[i]
+ model.DeleteUserGroupById(userId)
+ }
+
+ return Success(c, nil)
+}
+
+func UserGroupGetEndpoint(c echo.Context) error {
+ id := c.Param("id")
+
+ item, err := model.FindUserGroupById(id)
+ if err != nil {
+ return err
+ }
+
+ return Success(c, item)
+}
+
+func UserGroupAddMembersEndpoint(c echo.Context) error {
+ id := c.Param("id")
+
+ var items []string
+ if err := c.Bind(&items); err != nil {
+ return err
+ }
+
+ if err := model.AddUserGroupMembers(global.DB, items, id); err != nil {
+ return err
+ }
+ return Success(c, "")
+}
+
+func UserGroupDelMembersEndpoint(c echo.Context) (err error) {
+ id := c.Param("id")
+ memberIdsStr := c.Param("memberId")
+ memberIds := strings.Split(memberIdsStr, ",")
+ for i := range memberIds {
+ memberId := memberIds[i]
+ err = global.DB.Where("user_group_id = ? and user_id = ?", id, memberId).Delete(&model.UserGroupMember{}).Error
+ if err != nil {
+ return err
+ }
+ }
+
+ return Success(c, "")
+}
diff --git a/pkg/model/asset-group.go b/pkg/model/asset-group.go
new file mode 100644
index 0000000..8b53790
--- /dev/null
+++ b/pkg/model/asset-group.go
@@ -0,0 +1 @@
+package model
diff --git a/pkg/model/asset.go b/pkg/model/asset.go
index 38faf0e..7eaeafc 100644
--- a/pkg/model/asset.go
+++ b/pkg/model/asset.go
@@ -43,11 +43,6 @@ func (r *Asset) TableName() string {
return "assets"
}
-func FindAllAsset() (o []Asset, err error) {
- err = global.DB.Find(&o).Error
- return
-}
-
func FindAssetByConditions(protocol string, account User) (o []Asset, err error) {
db := global.DB.Table("assets").Select("assets.id,assets.name,assets.ip,assets.port,assets.protocol,assets.active,assets.owner,assets.created, users.nickname as owner_name,COUNT(resources.user_id) as sharer_count").Joins("left join users on assets.owner = users.id").Joins("left join resources on assets.id = resources.resource_id").Group("assets.id")
diff --git a/pkg/model/user-group-member.go b/pkg/model/user-group-member.go
new file mode 100644
index 0000000..2d2f4d2
--- /dev/null
+++ b/pkg/model/user-group-member.go
@@ -0,0 +1,11 @@
+package model
+
+type UserGroupMember struct {
+ ID string `gorm:"primary_key" json:"name"`
+ UserId string `json:"userId"`
+ UserGroupId string `json:"userGroupId"`
+}
+
+func (r *UserGroupMember) TableName() string {
+ return "user_group_members"
+}
diff --git a/pkg/model/user-group.go b/pkg/model/user-group.go
new file mode 100644
index 0000000..be55e90
--- /dev/null
+++ b/pkg/model/user-group.go
@@ -0,0 +1,97 @@
+package model
+
+import (
+ "gorm.io/gorm"
+ "next-terminal/pkg/global"
+ "next-terminal/pkg/utils"
+)
+
+type UserGroup struct {
+ ID string `gorm:"primary_key" json:"id"`
+ Name string `json:"name"`
+ Created utils.JsonTime `json:"created"`
+}
+
+type UserGroupVo struct {
+ ID string `gorm:"primary_key" json:"id"`
+ Name string `json:"name"`
+ Created utils.JsonTime `json:"created"`
+ MemberCount int64 `json:"memberCount"`
+}
+
+func (r *UserGroup) TableName() string {
+ return "user_groups"
+}
+
+func FindPageUserGroup(pageIndex, pageSize int, name string) (o []UserGroupVo, total int64, err error) {
+ db := global.DB.Table("user_groups").Select("user_groups.id, user_groups.name, user_groups.created, count(user_group_members.user_id) as member_count").Joins("left join user_group_members on user_groups.id = user_group_members.user_group_id").Group("user_groups.id")
+ dbCounter := global.DB.Table("user_groups")
+ if len(name) > 0 {
+ db = db.Where("user_groups.name like ?", "%"+name+"%")
+ dbCounter = dbCounter.Where("name like ?", "%"+name+"%")
+ }
+
+ err = dbCounter.Count(&total).Error
+ if err != nil {
+ return nil, 0, err
+ }
+ err = db.Order("user_groups.created desc").Find(&o).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Error
+ if o == nil {
+ o = make([]UserGroupVo, 0)
+ }
+ return
+}
+
+func CreateNewUserGroup(o *UserGroup, members []string) (err error) {
+ return global.DB.Transaction(func(tx *gorm.DB) error {
+ err = tx.Create(o).Error
+ if err != nil {
+ return err
+ }
+
+ if members != nil {
+ userGroupId := o.ID
+ err = AddUserGroupMembers(tx, members, userGroupId)
+ if err != nil {
+ return err
+ }
+ }
+ return err
+ })
+}
+
+func AddUserGroupMembers(tx *gorm.DB, userIds []string, userGroupId string) error {
+ for i := range userIds {
+ userId := userIds[i]
+ _, err := FindUserById(userId)
+ if err != nil {
+ return err
+ }
+
+ userGroupMember := UserGroupMember{
+ ID: utils.Sign([]string{userGroupId, userId}),
+ UserId: userId,
+ UserGroupId: userGroupId,
+ }
+ err = tx.Create(&userGroupMember).Error
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func FindUserGroupById(id string) (o UserGroup, err error) {
+ err = global.DB.Where("id = ?", id).First(&o).Error
+ return
+}
+
+func UpdateUserGroupById(o *UserGroup, id string) {
+ o.ID = id
+ global.DB.Updates(o)
+}
+
+func DeleteUserGroupById(id string) {
+ global.DB.Where("id = ?", id).Delete(&UserGroup{})
+ global.DB.Where("user_group_id = ?", id).Delete(&UserGroupMember{})
+}
diff --git a/web/src/App.js b/web/src/App.js
index 10b6881..14ae9f5 100644
--- a/web/src/App.js
+++ b/web/src/App.js
@@ -35,6 +35,7 @@ import Setting from "./components/setting/Setting";
import BatchCommand from "./components/command/BatchCommand";
import {NT_PACKAGE} from "./utils/utils";
import {isAdmin} from "./service/permission";
+import UserGroup from "./components/user/UserGroup";
const {Footer, Sider} = Layout;
@@ -188,25 +189,18 @@ class App extends Component {
- {/*}>*/}
- {/*
}>*/}
- {/* */}
- {/* 用户组管理*/}
- {/* */}
- {/* */}
-
- {/* }>*/}
- {/* */}
- {/* 用户管理*/}
- {/* */}
- {/* */}
- {/**/}
-
- }>
-
- 用户管理
-
-
+ }>
+ }>
+
+ 用户管理
+
+
+ }>
+
+ 用户组管理
+
+
+
> : undefined
}
@@ -246,6 +240,7 @@ class App extends Component {
+
diff --git a/web/src/components/asset/Asset.js b/web/src/components/asset/Asset.js
index 10e3b64..5eb8395 100644
--- a/web/src/components/asset/Asset.js
+++ b/web/src/components/asset/Asset.js
@@ -466,7 +466,7 @@ class Asset extends Component {
{isAdmin() ?
-
+