diff --git a/src/app.go b/src/app.go index a97474e5..f422066f 100644 --- a/src/app.go +++ b/src/app.go @@ -8,6 +8,7 @@ import ( "ems.agt/src/framework/errorcatch" "ems.agt/src/framework/middleware" "ems.agt/src/framework/middleware/security" + "ems.agt/src/modules/chart" "ems.agt/src/modules/common" "ems.agt/src/modules/crontask" "ems.agt/src/modules/monitor" @@ -120,6 +121,8 @@ func initModulesRoute(app *gin.Engine) { networkelement.Setup(app) // 跟踪模块 trace.Setup(app) + // 图表模块 + chart.Setup(app) // 调度任务模块--暂无接口 crontask.Setup(app) // 监控模块 - 含调度处理加入队列,放最后 diff --git a/src/modules/chart/chart.go b/src/modules/chart/chart.go new file mode 100644 index 00000000..ca402c19 --- /dev/null +++ b/src/modules/chart/chart.go @@ -0,0 +1,38 @@ +package chart + +import ( + "ems.agt/src/framework/logger" + "ems.agt/src/modules/chart/controller" + + "github.com/gin-gonic/gin" +) + +// 模块路由注册 +func Setup(router *gin.Engine) { + logger.Infof("开始加载 ====> chart 模块路由") + + chartGroup := router.Group("/chart") + + // 关系图 + chartGraphGroup := chartGroup.Group("/graph") + { + chartGraphGroup.GET("", + // middleware.PreAuthorize(nil), + controller.NewChartGraph.Load, + ) + chartGraphGroup.GET("/groups", + // middleware.PreAuthorize(nil), + controller.NewChartGraph.GroupNames, + ) + chartGraphGroup.POST("", + // middleware.PreAuthorize(nil), + // collectlogs.OperateLog(collectlogs.OptionNew("网元关系图", collectlogs.BUSINESS_TYPE_UPDATE)), + controller.NewChartGraph.Save, + ) + chartGraphGroup.DELETE("/:group", + // middleware.PreAuthorize(nil), + // collectlogs.OperateLog(collectlogs.OptionNew("网元关系图", collectlogs.BUSINESS_TYPE_UPDATE)), + controller.NewChartGraph.Delete, + ) + } +} diff --git a/src/modules/chart/controller/chart_graph.go b/src/modules/chart/controller/chart_graph.go new file mode 100644 index 00000000..a95d6729 --- /dev/null +++ b/src/modules/chart/controller/chart_graph.go @@ -0,0 +1,100 @@ +package controller + +import ( + "ems.agt/src/framework/i18n" + "ems.agt/src/framework/utils/ctx" + "ems.agt/src/framework/vo/result" + chartService "ems.agt/src/modules/chart/service" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +// 实例化控制层 ChartGraphController 结构体 +var NewChartGraph = &ChartGraphController{ + chartGraphService: chartService.NewChartGraphImpl, +} + +// G6关系图 +// +// PATH /graph +type ChartGraphController struct { + // G6关系图数据表服务 + chartGraphService chartService.IChartGraph +} + +// 获取关系图组名 +// +// GET /groups +func (s *ChartGraphController) GroupNames(c *gin.Context) { + data := s.chartGraphService.SelectGroup() + c.JSON(200, result.OkData(data)) +} + +// 获取关系图数据 +// +// GET / +func (s *ChartGraphController) Load(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + Group string `form:"group" binding:"required"` + Type string `form:"type" binding:"omitempty,oneof=node edge combo"` + } + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + data := s.chartGraphService.LoadData(querys.Group, querys.Type) + c.JSON(200, result.OkData(data)) +} + +// 保存关系图数据 +// +// POST / +func (s *ChartGraphController) Save(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + Group string `json:"group" binding:"required"` + Data struct { + Nodes []map[string]any `json:"nodes" binding:"required"` + Edges []map[string]any `json:"edges" binding:"required"` + Combos []map[string]any `json:"combos" binding:"required"` + } `json:"data" binding:"required"` + } + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + data := map[string]any{ + "nodes": body.Data.Nodes, + "edges": body.Data.Edges, + "combos": body.Data.Combos, + } + saveNum := s.chartGraphService.SaveData(body.Group, data) + if saveNum > 0 { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 删除关系图数据 +// +// DELETE /:group +func (s *ChartGraphController) Delete(c *gin.Context) { + language := ctx.AcceptLanguage(c) + group := c.Param("group") + if group == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + deleteNum := s.chartGraphService.DeleteGroup(group) + if deleteNum > 0 { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} diff --git a/src/modules/chart/model/chart_graph.go b/src/modules/chart/model/chart_graph.go new file mode 100644 index 00000000..26dd8231 --- /dev/null +++ b/src/modules/chart/model/chart_graph.go @@ -0,0 +1,31 @@ +package model + +// ChartGraph G6关系图数据对象 chart_graph +type ChartGraph struct { + RowID int64 `json:"rowId,omitempty" gorm:"column:row_id;primaryKey;autoIncrement"` // 记录ID + RowType string `json:"rowType,omitempty" gorm:"column:row_type"` // 记录类型(node/edge/combo) + RowGroup string `json:"rowGroup,omitempty" gorm:"column:row_group"` // 记录组名 + ID string `json:"id,omitempty" gorm:"column:id"` // 元素ID + Type string `json:"type,omitempty" gorm:"column:type"` // node/combo 类型 + Depth int `json:"depth,omitempty" gorm:"column:depth"` // node/combo 深度 + X float64 `json:"x,omitempty" gorm:"column:x"` // node/combo 横向坐标 + Y float64 `json:"y,omitempty" gorm:"column:y"` // node/combo 纵向坐标 + Size string `json:"size,omitempty" gorm:"column:size"` // node/combo 大小-JSON数组 + Icon string `json:"icon,omitempty" gorm:"column:icon"` // node-部分类型支持图标JSON配置 + Img string `json:"img,omitempty" gorm:"column:img"` // node-img 图片 + ClipCfg string `json:"clipCfg,omitempty" gorm:"column:clip_cfg"` // node-img 图片裁剪JSON配置 + Direction string `json:"direction,omitempty" gorm:"column:direction"` // node-triangle 三角形的方向(up/down/left/right) + Source string `json:"source,omitempty" gorm:"column:source"` // edge-边起始 + Target string `json:"target,omitempty" gorm:"column:target"` // edge-边目标 + ComboID string `json:"combo_id,omitempty" gorm:"column:combo_id"` // combo-分组 + Padding string `json:"padding,omitempty" gorm:"column:padding"` // combo-JSON分组内边距 + ParentID string `json:"parentId,omitempty" gorm:"column:parent_id"` // combo-父级分组 + Children string `json:"children,omitempty" gorm:"column:children"` // combo-JSON分组内含元素 + Style string `json:"style,omitempty" gorm:"column:style"` // 元素样式-JONS配置 + Label string `json:"label,omitempty" gorm:"column:label"` // 标签文本 + LabelCfg string `json:"labelCfg,omitempty" gorm:"column:label_cfg"` // 标签文本-JSON配置 +} + +func (ChartGraph) TableName() string { + return "chart_graph" +} diff --git a/src/modules/chart/repository/chart_graph.go b/src/modules/chart/repository/chart_graph.go new file mode 100644 index 00000000..d930fb69 --- /dev/null +++ b/src/modules/chart/repository/chart_graph.go @@ -0,0 +1,21 @@ +package repository + +import "ems.agt/src/modules/chart/model" + +// G6关系图数据 数据层接口 +type IChartGraph interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(graph model.ChartGraph) []model.ChartGraph + + // SelectGroup 查询组名 + SelectGroup() []string + + // Insert 批量添加 + Inserts(graphs []model.ChartGraph) int64 + + // Delete 删除组数据 + DeleteGroup(rowGroup string) int64 +} diff --git a/src/modules/chart/repository/chart_graph.impl.go b/src/modules/chart/repository/chart_graph.impl.go new file mode 100644 index 00000000..e25802b7 --- /dev/null +++ b/src/modules/chart/repository/chart_graph.impl.go @@ -0,0 +1,194 @@ +package repository + +import ( + "strings" + + "ems.agt/src/framework/datasource" + "ems.agt/src/framework/logger" + "ems.agt/src/framework/utils/parse" + "ems.agt/src/framework/utils/repo" + "ems.agt/src/modules/chart/model" +) + +// 实例化数据层 NewChartGraphImpl 结构体 +var NewChartGraphImpl = &ChartGraphImpl{ + selectSql: `select + row_id, row_type, row_group, + id, type, depth, x, y, size, icon, img, + clip_cfg, direction, + source, target, combo_id, + padding, parent_id, children, + style, label, label_cfg + from chart_graph`, + + resultMap: map[string]string{ + "row_id": "RowID", + "row_type": "RowType", + "row_group": "RowGroup", + "id": "ID", + "type": "Type", + "depth": "Depth", + "x": "X", + "y": "Y", + "size": "Size", + "icon": "Icon", + "img": "Img", + "clip_cfg": "ClipCfg", + "direction": "Direction", + "source": "Source", + "target": "Target", + "combo_id": "ComboID", + "padding": "Padding", + "parent_id": "ParentID", + "children": "Children", + "style": "Style", + "label": "Label", + "label_cfg": "LabelCfg", + }, +} + +// ChartGraphImpl G6关系图数据表 数据层处理 +type ChartGraphImpl struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *ChartGraphImpl) convertResultRows(rows []map[string]any) []model.ChartGraph { + arr := make([]model.ChartGraph, 0) + for _, row := range rows { + item := model.ChartGraph{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// SelectPage 根据条件分页查询字典类型 +func (r *ChartGraphImpl) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["rowType"]; ok && v != "" { + conditions = append(conditions, "row_type = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["rowGroup"]; ok && v != "" { + conditions = append(conditions, "row_group = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.ChartGraph{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from chart_graph" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return result + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *ChartGraphImpl) SelectList(graph model.ChartGraph) []model.ChartGraph { + // 查询条件拼接 + var conditions []string + var params []any + if graph.RowType != "" { + conditions = append(conditions, "row_type = ?") + params = append(params, graph.RowType) + } + if graph.RowGroup != "" { + conditions = append(conditions, "row_group = ?") + params = append(params, graph.RowGroup) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by depth asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectGroup 查询组名 +func (r *ChartGraphImpl) SelectGroup() []string { + rows := []string{} + // 查询数量 长度为0直接返回 + querySql := "select row_group as 'str' from chart_graph GROUP BY row_group" + strRows, err := datasource.RawDB("", querySql, nil) + if err != nil { + logger.Errorf("Query err => %v", err) + return rows + } + for _, v := range strRows { + rows = append(rows, v["str"].(string)) + } + return rows +} + +// Insert 批量添加 +func (r *ChartGraphImpl) Inserts(graphs []model.ChartGraph) int64 { + tx := datasource.DefaultDB().CreateInBatches(graphs, 2000) + if err := tx.Error; err != nil { + logger.Errorf("CreateInBatches err => %v", err) + } + return tx.RowsAffected +} + +// Delete 删除组数据 +func (r *ChartGraphImpl) DeleteGroup(rowGroup string) int64 { + tx := datasource.DefaultDB().Where("row_group = ?", rowGroup).Delete(&model.ChartGraph{}) + if err := tx.Error; err != nil { + logger.Errorf("Delete err => %v", err) + } + return tx.RowsAffected +} diff --git a/src/modules/chart/service/chart_graph.go b/src/modules/chart/service/chart_graph.go new file mode 100644 index 00000000..470183d3 --- /dev/null +++ b/src/modules/chart/service/chart_graph.go @@ -0,0 +1,16 @@ +package service + +// G6关系图数据 服务层接口 +type IChartGraph interface { + // SelectGroup 查询组名 + SelectGroup() []string + + // LoadData 查询所组图数据 + LoadData(rowGroup, rowType string) map[string]any + + // SaveData 添加组图数据 + SaveData(rowGroup string, data map[string]any) int64 + + // DeleteGroup 删除所组图数据 + DeleteGroup(rowGroup string) int64 +} diff --git a/src/modules/chart/service/chart_graph.impl.go b/src/modules/chart/service/chart_graph.impl.go new file mode 100644 index 00000000..26d61c6e --- /dev/null +++ b/src/modules/chart/service/chart_graph.impl.go @@ -0,0 +1,359 @@ +package service + +import ( + "strings" + + "ems.agt/src/framework/utils/parse" + "ems.agt/src/modules/chart/model" + chartRepository "ems.agt/src/modules/chart/repository" + "github.com/goccy/go-json" +) + +// 实例化服务层 ChartGraphImpl 结构体 +var NewChartGraphImpl = &ChartGraphImpl{ + graphRepository: chartRepository.NewChartGraphImpl, +} + +// ChartGraphImpl G6关系图数据表 服务层处理 +type ChartGraphImpl struct { + // G6关系图数据服务 + graphRepository chartRepository.IChartGraph +} + +// SelectGroup 查询组名 +func (s *ChartGraphImpl) SelectGroup() []string { + return s.graphRepository.SelectGroup() +} + +// LoadData 查询所组图数据 +func (s *ChartGraphImpl) LoadData(rowGroup, rowType string) map[string]any { + // 查询数据 + graph := model.ChartGraph{ + RowGroup: rowGroup, + } + if rowType != "" { + graph.RowType = rowType + } + data := s.graphRepository.SelectList(graph) + + // 数据项 + nodes := []map[string]any{} + edges := []map[string]any{} + combos := []map[string]any{} + + for _, v := range data { + if v.RowType == "node" { + nodes = append(nodes, s.loadNode(v)) + } + if v.RowType == "edge" { + edges = append(edges, s.loadEdge(v)) + } + if v.RowType == "combo" { + combos = append(combos, s.loadCombo(v)) + } + } + + return map[string]any{ + "nodes": nodes, + "edges": edges, + "combos": combos, + } +} + +// loadNode 图数据Node +func (s *ChartGraphImpl) loadNode(v model.ChartGraph) map[string]any { + node := map[string]any{ + "id": v.ID, + "comboId": v.ComboID, + "x": v.X, + "y": v.Y, + "type": v.Type, + "depth": v.Depth, + } + + // 元素样式 + style := map[string]any{} + if len(v.Style) > 7 { + json.Unmarshal([]byte(v.Style), &style) + } + node["style"] = style + + // 元素大小 + if strings.Contains(v.Size, "[") { + sizeArr := []int64{} + json.Unmarshal([]byte(v.Size), &sizeArr) + node["size"] = sizeArr + } else { + node["size"] = parse.Number(v.Size) + } + + // 标签文本 + node["label"] = v.Label + labelCfg := map[string]any{} + if len(v.LabelCfg) > 7 { + json.Unmarshal([]byte(v.LabelCfg), &labelCfg) + } + node["labelCfg"] = labelCfg + + // 三角形属性 + if v.Type == "triangle" { + node["direction"] = v.Direction + } + + // 图片属性 + if v.Type == "image" { + node["img"] = v.Img + clipCfg := map[string]any{} + if len(v.ClipCfg) > 7 { + json.Unmarshal([]byte(v.ClipCfg), &clipCfg) + } + node["clipCfg"] = clipCfg + } + + // 图标属性 + if v.Icon != "" { + icon := map[string]any{} + if len(v.Icon) > 7 { + json.Unmarshal([]byte(v.Icon), &icon) + } + node["icon"] = icon + } + + return node +} + +// loadEdge 图数据Edge +func (s *ChartGraphImpl) loadEdge(v model.ChartGraph) map[string]any { + edge := map[string]any{ + "id": v.ID, + "source": v.Source, + "target": v.Target, + "type": v.Type, + } + + // 元素样式 + style := map[string]any{} + if len(v.Style) > 7 { + json.Unmarshal([]byte(v.Style), &style) + } + edge["style"] = style + + // 标签文本 + edge["label"] = v.Label + labelCfg := map[string]any{} + if len(v.LabelCfg) > 7 { + json.Unmarshal([]byte(v.LabelCfg), &labelCfg) + } + edge["labelCfg"] = labelCfg + + return edge +} + +// loadCombo 图数据Combo +func (s *ChartGraphImpl) loadCombo(v model.ChartGraph) map[string]any { + combo := map[string]any{ + "id": v.ID, + "x": v.X, + "y": v.Y, + "type": v.Type, + "depth": v.Depth, + } + + // 元素样式 + style := map[string]any{} + if len(v.Style) > 7 { + json.Unmarshal([]byte(v.Style), &style) + } + combo["style"] = style + + // 元素大小 + if strings.Contains(v.Size, "[") { + sizeArr := []int64{} + json.Unmarshal([]byte(v.Size), &sizeArr) + combo["size"] = sizeArr + } else { + combo["size"] = parse.Number(v.Size) + } + + // 元素内边距 + if strings.Contains(v.Padding, "[") { + paddingArr := []int64{} + json.Unmarshal([]byte(v.Padding), &paddingArr) + combo["padding"] = paddingArr + } else { + combo["padding"] = parse.Number(v.Padding) + } + + // 标签文本 + combo["label"] = v.Label + labelCfg := map[string]any{} + if len(v.LabelCfg) > 7 { + json.Unmarshal([]byte(v.LabelCfg), &labelCfg) + } + combo["labelCfg"] = labelCfg + + // 分组内元素 + if v.Children != "" { + children := []map[string]any{} + if len(v.Children) > 7 { + json.Unmarshal([]byte(v.Children), &children) + } + combo["children"] = children + } + + return combo +} + +// SaveData 添加组图数据 +func (s *ChartGraphImpl) SaveData(rowGroup string, data map[string]any) int64 { + graphs := []model.ChartGraph{} + nodes := data["nodes"].([]map[string]any) + graphNodes := s.saveNode(rowGroup, nodes) + graphs = append(graphs, graphNodes...) + edges := data["edges"].([]map[string]any) + graphEdges := s.saveEdge(rowGroup, edges) + graphs = append(graphs, graphEdges...) + combos := data["combos"].([]map[string]any) + graphCombos := s.saveCombo(rowGroup, combos) + graphs = append(graphs, graphCombos...) + // 删除组数据后插入 + if len(graphs) > 0 { + s.graphRepository.DeleteGroup(rowGroup) + } + return s.graphRepository.Inserts(graphs) +} + +// saveNode 图数据Node +func (s *ChartGraphImpl) saveNode(rowGroup string, nodes []map[string]any) []model.ChartGraph { + var graphs []model.ChartGraph + for _, v := range nodes { + node := model.ChartGraph{ + RowType: "node", + RowGroup: rowGroup, + ID: v["id"].(string), + X: v["x"].(float64), + Y: v["y"].(float64), + Type: v["type"].(string), + } + if comboId, ok := v["comboId"]; ok && comboId != nil { + node.ComboID = comboId.(string) + } + if depth, ok := v["depth"]; ok && depth != nil { + node.Depth = int(depth.(float64)) + } + if styleByte, err := json.Marshal(v["style"]); err == nil { + node.Style = string(styleByte) + } + + // 元素大小 + if sizeByte, err := json.Marshal(v["size"]); err == nil { + node.Size = string(sizeByte) + } + + // 标签文本 + if label, ok := v["label"]; ok && label != nil { + node.Label = label.(string) + } + if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil { + node.LabelCfg = string(labelCfgByte) + } + // 三角形属性 + if direction, ok := v["direction"]; ok && direction != nil && node.Type == "triangle" { + node.Direction = direction.(string) + } + // 图片属性 + if img, ok := v["img"]; ok && img != nil { + node.Img = img.(string) + if clipCfgByte, err := json.Marshal(v["clipCfg"]); err == nil { + node.ClipCfg = string(clipCfgByte) + } + } + // 图标属性 + if icon, ok := v["icon"]; ok && icon != nil { + if iconByte, err := json.Marshal(icon); err == nil { + node.Icon = string(iconByte) + } + } + + graphs = append(graphs, node) + } + return graphs +} + +// saveEdge 图数据Edge +func (s *ChartGraphImpl) saveEdge(rowGroup string, edges []map[string]any) []model.ChartGraph { + var graphs []model.ChartGraph + for _, v := range edges { + edge := model.ChartGraph{ + RowType: "edge", + RowGroup: rowGroup, + ID: v["id"].(string), + Source: v["source"].(string), + Target: v["target"].(string), + Type: v["type"].(string), + } + + if styleByte, err := json.Marshal(v["style"]); err == nil { + edge.Style = string(styleByte) + } + + // 标签文本 + if label, ok := v["label"]; ok && label != nil { + edge.Label = label.(string) + } + if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil { + edge.LabelCfg = string(labelCfgByte) + } + + graphs = append(graphs, edge) + } + return graphs +} + +// saveCombo 图数据Combo +func (s *ChartGraphImpl) saveCombo(rowGroup string, combos []map[string]any) []model.ChartGraph { + var graphs []model.ChartGraph + for _, v := range combos { + combo := model.ChartGraph{ + RowType: "combo", + RowGroup: rowGroup, + ID: v["id"].(string), + X: v["x"].(float64), + Y: v["y"].(float64), + Type: v["type"].(string), + } + if depth, ok := v["depth"]; ok && depth != nil { + combo.Depth = int(depth.(float64)) + } + if styleByte, err := json.Marshal(v["style"]); err == nil { + combo.Style = string(styleByte) + } + if paddingByte, err := json.Marshal(v["padding"]); err == nil { + combo.Padding = string(paddingByte) + } + if childrenByte, err := json.Marshal(v["children"]); err == nil { + combo.Children = string(childrenByte) + } + + // 元素大小 + if sizeByte, err := json.Marshal(v["size"]); err == nil { + combo.Size = string(sizeByte) + } + + // 标签文本 + if label, ok := v["label"]; ok && label != nil { + combo.Label = label.(string) + } + if labelCfgByte, err := json.Marshal(v["labelCfg"]); err == nil { + combo.LabelCfg = string(labelCfgByte) + } + + graphs = append(graphs, combo) + } + return graphs +} + +// Delete 删除所组图数据 +func (s *ChartGraphImpl) DeleteGroup(rowGroup string) int64 { + return s.graphRepository.DeleteGroup(rowGroup) +}