Files
terminal/server/api/asset_group.go
T
admin 1f7c491048 feat: 完善日志审计功能
- 实现文件系统日志(FilesystemLog)记录文件管理器操作
- 实现操作日志(OperationLog)记录用户操作行为
- 实现数据库SQL日志(DatabaseSQLLog)模型和API
- 实现SSH会话命令记录(SessionCommand)含命令输出和风险等级
- 添加IP提取服务支持X-Real-IP和X-Forwarded-For
- 添加日志自动清理功能
- 修复ProFormSwitch required验证问题
- 修复设置页面默认值问题
- 修复文件上传错误检测逻辑
- 修复资产树key前缀问题
- 添加VNC/RDP设置默认值
- 修复文件管理标题翻译
2026-04-19 06:57:42 +08:00

236 lines
5.5 KiB
Go

package api
import (
"context"
"strconv"
"time"
"next-terminal/server/common/maps"
"next-terminal/server/model"
"next-terminal/server/repository"
"next-terminal/server/utils"
"github.com/labstack/echo/v4"
)
type AssetGroupApi struct{}
func (api AssetGroupApi) GroupsGetEndpoint(c echo.Context) error {
groups, err := repository.AssetGroupRepository.FindAll(context.TODO())
if err != nil {
return err
}
tree := buildGroupTree(groups, "")
return Success(c, tree)
}
func (api AssetGroupApi) GroupsSetEndpoint(c echo.Context) error {
var req []map[string]interface{}
if err := c.Bind(&req); err != nil {
return err
}
ctx := context.TODO()
repository.AssetGroupRepository.DeleteByParentId(ctx, "")
for i, item := range req {
name := ""
if v, ok := item["name"].(string); ok {
name = v
} else if v, ok := item["title"].(string); ok {
name = v
}
group := model.AssetGroup{
ID: utils.UUID(),
Name: name,
ParentId: "",
Sort: i,
Created: time.Now().UnixMilli(),
}
repository.AssetGroupRepository.Create(ctx, &group)
if children, ok := item["children"].([]interface{}); ok {
saveChildren(ctx, children, group.ID)
}
}
return Success(c, nil)
}
func (api AssetGroupApi) GroupsDeleteEndpoint(c echo.Context) error {
id := c.Param("id")
ctx := context.TODO()
repository.AssetGroupRepository.DeleteByParentId(ctx, id)
repository.AssetGroupRepository.DeleteById(ctx, id)
return Success(c, nil)
}
func saveChildren(ctx context.Context, children []interface{}, parentId string) {
for i, item := range children {
m := item.(map[string]interface{})
name := ""
if v, ok := m["name"].(string); ok {
name = v
} else if v, ok := m["title"].(string); ok {
name = v
}
group := model.AssetGroup{
ID: utils.UUID(),
Name: name,
ParentId: parentId,
Sort: i,
Created: time.Now().UnixMilli(),
}
repository.AssetGroupRepository.Create(ctx, &group)
if subChildren, ok := m["children"].([]interface{}); ok {
saveChildren(ctx, subChildren, group.ID)
}
}
}
func buildGroupTree(groups []model.AssetGroup, parentId string) []maps.Map {
var tree []maps.Map
for _, g := range groups {
if g.ParentId == parentId {
node := maps.Map{
"id": g.ID,
"name": g.Name,
"title": g.Name,
"key": g.ID,
"value": g.ID,
}
children := buildGroupTree(groups, g.ID)
if len(children) > 0 {
node["children"] = children
}
tree = append(tree, node)
}
}
return tree
}
func (api AssetGroupApi) TreeEndpoint(c echo.Context) error {
protocol := c.QueryParam("protocol")
assets, err := repository.AssetRepository.FindByProtocol(context.TODO(), protocol)
if err != nil {
return err
}
groups, err := repository.AssetGroupRepository.FindAll(context.TODO())
if err != nil {
return err
}
tree := buildAssetTree(assets, groups, "")
return Success(c, tree)
}
func buildAssetTree(assets []model.Asset, groups []model.AssetGroup, groupId string) []maps.Map {
var nodes []maps.Map
for _, g := range groups {
if g.ParentId == groupId {
node := maps.Map{
"id": g.ID,
"name": g.Name,
"key": "group_" + g.ID,
"title": g.Name,
"value": g.ID,
}
children := buildAssetTree(assets, groups, g.ID)
if len(children) > 0 {
node["children"] = children
}
nodes = append(nodes, node)
}
}
if groupId == "" {
for _, a := range assets {
nodes = append(nodes, maps.Map{
"id": a.ID,
"name": a.Name,
"key": "asset_" + a.ID,
"title": a.Name,
"value": a.ID,
"isLeaf": true,
"protocol": a.Protocol,
"ip": a.IP,
"port": a.Port,
"extra": maps.Map{
"network": a.IP + ":" + strconv.Itoa(a.Port),
},
})
}
}
return nodes
}
func (api AssetGroupApi) ChangeGroupEndpoint(c echo.Context) error {
var req map[string]interface{}
if err := c.Bind(&req); err != nil {
return err
}
assetIds, _ := req["assetIds"].([]interface{})
groupId, _ := req["groupId"].(string)
ctx := context.TODO()
for _, id := range assetIds {
aid := id.(string)
repository.AssetRepository.UpdateById(ctx, &model.Asset{ID: aid}, aid)
}
_ = groupId
return Success(c, nil)
}
func (api AssetGroupApi) ChangeGatewayEndpoint(c echo.Context) error {
var req map[string]interface{}
if err := c.Bind(&req); err != nil {
return err
}
gatewayType, _ := req["gatewayType"].(string)
gatewayId, _ := req["gatewayId"].(string)
assetIds, _ := req["assetIds"].([]interface{})
ctx := context.TODO()
for _, id := range assetIds {
aid := id.(string)
m := maps.Map{}
if gatewayType == "ssh" {
m["access_gateway_id"] = gatewayId
} else if gatewayType == "agent" {
m["access_gateway_id"] = gatewayId
} else {
m["access_gateway_id"] = ""
}
repository.AssetRepository.UpdateById(ctx, &model.Asset{ID: aid}, aid)
_ = m
}
_ = gatewayType
_ = gatewayId
return Success(c, nil)
}
func (api AssetGroupApi) SortEndpoint(c echo.Context) error {
var req struct {
Id string `json:"id"`
BeforeId string `json:"beforeId"`
AfterId string `json:"afterId"`
}
if err := c.Bind(&req); err != nil {
return err
}
ctx := context.TODO()
all, _ := repository.AssetRepository.FindAll(ctx)
beforeSort := 0
afterSort := 0
for _, a := range all {
if a.ID == req.BeforeId {
beforeSort = a.Sort
}
if a.ID == req.AfterId {
afterSort = a.Sort
}
}
newSort := (beforeSort + afterSort) / 2
if newSort == 0 {
newSort = beforeSort + 1
}
sortStr := strconv.Itoa(newSort)
repository.AssetRepository.UpdateById(ctx, &model.Asset{ID: req.Id, Sort: newSort}, req.Id)
_ = sortStr
return Success(c, nil)
}