diff --git a/src/modules/practical_training/controller/pt_ne_config_data.go b/src/modules/practical_training/controller/pt_ne_config_data.go index 30a07084..ccb7db65 100644 --- a/src/modules/practical_training/controller/pt_ne_config_data.go +++ b/src/modules/practical_training/controller/pt_ne_config_data.go @@ -2,6 +2,7 @@ package controller import ( "encoding/json" + "strings" "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" @@ -76,23 +77,14 @@ func (s *PtNeConfigDataController) ResetAsDefault(c *gin.Context) { language := ctx.AcceptLanguage(c) var body struct { NeType string `json:"neType" binding:"required"` // 网元类型 - NeId string `json:"neid" binding:"required"` // 网元ID } if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } - stubType := "" // 存根数据类型 0系统 1班级 2个人 - loginUser, _ := ctx.LoginUser(c) - for _, v := range loginUser.User.Roles { - if v.RoleKey == "student" { - stubType = "2" - } else if v.RoleKey == "teacher" { - stubType = "1" - } - } - operaUserName := loginUser.User.NickName + stubType := "2" // 存根数据类型 0系统 1班级 2个人 + operaUserName := ctx.LoginUserToUserName(c) s.ptNeConfigDataService.ResetAsDefaultByType(body.NeType, stubType, operaUserName) c.JSON(200, result.Ok(nil)) @@ -114,6 +106,7 @@ func (s *PtNeConfigDataController) Info(c *gin.Context) { // 优先查询个人的数据,没有就向系统取 param := model.PtNeConfigData{ + CreateBy: ctx.LoginUserToUserName(c), NeType: querys.NeType, StubType: "2", ParamName: querys.ParamName, @@ -122,9 +115,10 @@ func (s *PtNeConfigDataController) Info(c *gin.Context) { // 输出数据内容 if info.ParamJson != "" { - data := info.ParamData - data["paramType"] = info.ParamType - c.JSON(200, result.Ok(data)) + c.JSON(200, result.Ok(map[string]any{ + "paramType": info.ParamType, + "paramData": info.ParamData, + })) return } c.JSON(200, result.Err(nil)) @@ -135,7 +129,12 @@ func (s *PtNeConfigDataController) Info(c *gin.Context) { // PUT / func (s *PtNeConfigDataController) Edit(c *gin.Context) { language := ctx.AcceptLanguage(c) - var body model.PtNeConfigData + var body struct { + NeType string `json:"neType" binding:"required"` // 网元类型 + ParamName string `json:"paramName" binding:"required"` + ParamData map[string]any `json:"paramData" binding:"required"` + Loc string `json:"loc"` // 仅array使用与数据对象内index一致,有多层时划分嵌套层(index/subParamName/index) + } if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return @@ -150,11 +149,6 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) { ParamName: body.ParamName, } info := s.ptNeConfigDataService.SelectByStubType(param) - idx, idxOk := body.ParamData["index"] - if info.ParamType == "array" && !idxOk { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) - return - } changeLog := model.PtNeConfigDataLog{ CreateBy: currentUserName, StubType: info.StubType, @@ -163,35 +157,56 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) { ParamDisplay: info.ParamDisplay, ParamType: info.ParamType, OperaType: 2, + ParamJsonOld: info.ParamJson, } - // 要修改的属性 - if infoDataArr, ok := info.ParamData["data"]; ok { - arr := infoDataArr.([]any) - // 单层 - if info.ParamType == "list" && len(arr) == 1 { - for k, v := range body.ParamData { - item := arr[0].(map[string]any) - if _, ok := item[k]; ok { - item[k] = v - arr[0] = item - } + // 单层修改的属性 + if info.ParamType == "list" && len(info.ParamData) == 1 { + for k, v := range body.ParamData { + item := info.ParamData[0] + if _, ok := item[k]; ok { + item[k] = v } + info.ParamData[0] = item } - // 多层 - if info.ParamType == "array" { - if len(arr) == 0 { - arr = []any{body.ParamData} - } else { - idx := parse.Number(idx) - if idx < 0 || int(idx) >= len(arr) { - c.JSON(400, result.CodeMsg(400, "index over data step")) + } + // 多层修改的属性 + if info.ParamType == "array" { + if body.Loc == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 检查层级 + locArr := strings.Split(body.Loc, "/") + loc := parse.Number(locArr[0]) + if loc < 0 || int(loc) >= len(info.ParamData) { + c.JSON(400, result.CodeMsg(400, "loc over data step")) + return + } + + if len(info.ParamData) == 0 { + c.JSON(400, result.CodeMsg(400, "loc over data step")) + return + } + if len(locArr) == 1 { + body.ParamData["index"] = loc + info.ParamData[loc] = body.ParamData + } + if len(locArr) > 2 { + item := info.ParamData[loc] + if a, ok := item[locArr[1]]; ok { + arr := a.([]any) + aLoc := parse.Number(locArr[2]) + if aLoc < 0 || int(aLoc) >= len(arr) { + c.JSON(400, result.CodeMsg(400, locArr[1]+" loc over data step")) return } - arr[idx] = body.ParamData + body.ParamData["index"] = aLoc + arr[aLoc] = body.ParamData + item[locArr[1]] = arr } + info.ParamData[loc] = item } - info.ParamData["data"] = arr } // 将json数据转字符串存储 @@ -200,7 +215,6 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) { c.JSON(400, result.CodeMsg(400, err.Error())) return } - changeLog.ParamJsonOld = info.ParamJson info.ParamJson = string(paramDataByte) changeLog.ParamJsonNew = info.ParamJson @@ -230,7 +244,12 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) { // POST / func (s *PtNeConfigDataController) Add(c *gin.Context) { language := ctx.AcceptLanguage(c) - var body model.PtNeConfigData + var body struct { + NeType string `json:"neType" binding:"required"` // 网元类型 + ParamName string `json:"paramName" binding:"required"` // 根据配置可选值 + ParamData map[string]any `json:"paramData" binding:"required"` // 数据对象 + Loc string `json:"loc" binding:"required"` // 与数据对象内index一致,有多层时划分嵌套层(index/subParamName/index) + } if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return @@ -245,13 +264,15 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) { ParamName: body.ParamName, } info := s.ptNeConfigDataService.SelectByStubType(param) - if info.ParamType != "array" { - c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) + if info.ParamType != "array" || body.Loc == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } - idx, idxOk := body.ParamData["index"] - if info.ParamType == "array" && !idxOk { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + // 检查层级 + locArr := strings.Split(body.Loc, "/") + loc := parse.Number(locArr[0]) + if loc < 0 || int(loc) < len(info.ParamData) { + c.JSON(400, result.CodeMsg(400, "loc less data step")) return } changeLog := model.PtNeConfigDataLog{ @@ -262,24 +283,28 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) { ParamDisplay: info.ParamDisplay, ParamType: info.ParamType, OperaType: 1, + ParamJsonOld: info.ParamJson, } - // 要修改的属性 - if infoDataArr, ok := info.ParamData["data"]; ok { - arr := infoDataArr.([]any) - if len(arr) == 0 { - body.ParamData["index"] = 0 - arr = []any{body.ParamData} - } else { - idx := parse.Number(idx) - if idx < 0 || int(idx) < len(arr) { - c.JSON(400, result.CodeMsg(400, "index less than data step")) + // 要新增的属性 + if len(locArr) == 1 { + body.ParamData["index"] = len(info.ParamData) + info.ParamData = append(info.ParamData, body.ParamData) + } + if len(locArr) > 2 { + item := info.ParamData[loc] + if a, ok := item[locArr[1]]; ok { + arr := a.([]any) + aLoc := parse.Number(locArr[2]) + if loc < 0 || int(aLoc) < len(arr) { + c.JSON(400, result.CodeMsg(400, locArr[1]+" loc less data step")) return } body.ParamData["index"] = len(arr) arr = append(arr, body.ParamData) + item[locArr[1]] = arr } - info.ParamData["data"] = arr + info.ParamData[loc] = item } // 将json数据转字符串存储 @@ -288,7 +313,6 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) { c.JSON(400, result.CodeMsg(400, err.Error())) return } - changeLog.ParamJsonOld = info.ParamJson info.ParamJson = string(paramDataByte) changeLog.ParamJsonNew = info.ParamJson @@ -319,9 +343,9 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) { func (s *PtNeConfigDataController) Remove(c *gin.Context) { language := ctx.AcceptLanguage(c) var query struct { - Index int64 `form:"index" binding:"required"` //定位变更数据项 - NeType string `form:"neType" binding:"required"` // 网元类型 - ParamName string `form:"paramName" binding:"required"` // 根据配置可选值 + NeType string `form:"neType" binding:"required"` // 网元类型 + ParamName string `form:"paramName" binding:"required"` + Loc string `form:"loc" binding:"required"` // 与数据对象内index一致,有多层时划分嵌套层(index/subParamName/index) } if err := c.ShouldBindQuery(&query); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) @@ -337,10 +361,18 @@ func (s *PtNeConfigDataController) Remove(c *gin.Context) { ParamName: query.ParamName, } info := s.ptNeConfigDataService.SelectByStubType(param) - if info.ParamType != "array" { - c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) + if info.ParamType != "array" || query.Loc == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } + // 检查层级 + locArr := strings.Split(query.Loc, "/") + loc := parse.Number(locArr[0]) + if loc < 0 || int(loc) >= len(info.ParamData) { + c.JSON(400, result.CodeMsg(400, "loc over data step")) + return + } + // 变更日志 changeLog := model.PtNeConfigDataLog{ CreateBy: currentUserName, StubType: info.StubType, @@ -349,29 +381,25 @@ func (s *PtNeConfigDataController) Remove(c *gin.Context) { ParamDisplay: info.ParamDisplay, ParamType: info.ParamType, OperaType: 3, + ParamJsonOld: info.ParamJson, } - // 要修改的属性 - if infoDataArr, ok := info.ParamData["data"]; ok { - arr := infoDataArr.([]any) - if len(arr) == 0 { - c.JSON(400, result.CodeMsg(400, "index over data step")) - return - } else { - idx := parse.Number(query.Index) - if idx < 0 || int(idx) >= len(arr) { - c.JSON(400, result.CodeMsg(400, "index over data step")) + // 要删除的属性 + if len(locArr) == 1 { + info.ParamData = append(info.ParamData[:loc], info.ParamData[loc+1:]...) + } + if len(locArr) > 2 { + item := info.ParamData[loc] + if a, ok := item[locArr[1]]; ok { + arr := a.([]any) + aLoc := parse.Number(locArr[2]) + if aLoc < 0 || int(aLoc) >= len(arr) { + c.JSON(400, result.CodeMsg(400, locArr[1]+" loc over data step")) return } - // 删除后重排index序号 - arr = append(arr[:idx], arr[idx+1:]...) - for i := 0; i < len(arr); i++ { - item := arr[i].(map[string]any) - item["index"] = i - arr[i] = item - } + item[locArr[1]] = append(arr[:aLoc], arr[aLoc+1:]...) } - info.ParamData["data"] = arr + info.ParamData[loc] = item } // 将json数据转字符串存储 @@ -380,9 +408,30 @@ func (s *PtNeConfigDataController) Remove(c *gin.Context) { c.JSON(400, result.CodeMsg(400, err.Error())) return } - changeLog.ParamJsonOld = info.ParamJson + changeLog.ParamJsonNew = string(paramDataByte) + + // 删除后重排index序号 + if len(locArr) == 1 { + for i, v := range info.ParamData { + v["index"] = i + info.ParamData[i] = v + } + } + if len(locArr) > 2 { + item := info.ParamData[loc] + if a, ok := item[locArr[1]]; ok { + arr := a.([]any) + for i, v := range arr { + item := v.(map[string]any) + item["index"] = i + arr[i] = v + } + item[locArr[1]] = arr + } + info.ParamData[loc] = item + } + paramDataByte, _ = json.Marshal(info.ParamData) info.ParamJson = string(paramDataByte) - changeLog.ParamJsonNew = info.ParamJson // 个人有数据就更新 if info.StubType == "2" { diff --git a/src/modules/practical_training/model/pt_ne_config_data.go b/src/modules/practical_training/model/pt_ne_config_data.go index 15863396..ce2d4c09 100644 --- a/src/modules/practical_training/model/pt_ne_config_data.go +++ b/src/modules/practical_training/model/pt_ne_config_data.go @@ -17,7 +17,7 @@ type PtNeConfigData struct { // ====== 非数据库字段属性 ====== - ParamData map[string]any `json:"paramData,omitempty" binding:"required" gorm:"-"` // 与ParamJson配合转换 + ParamData []map[string]any `json:"paramData,omitempty" binding:"required" gorm:"-"` // 与ParamJson配合转换 } // TableName 表名称 diff --git a/src/modules/practical_training/model/pt_ne_config_data_log.go b/src/modules/practical_training/model/pt_ne_config_data_log.go index 785f5253..6ec92154 100644 --- a/src/modules/practical_training/model/pt_ne_config_data_log.go +++ b/src/modules/practical_training/model/pt_ne_config_data_log.go @@ -2,17 +2,17 @@ package model // PtNeConfigDataLog 实训教学_网元参数配置数据变更日志 type PtNeConfigDataLog struct { - ID string `json:"id" gorm:"id"` // ID - CreateBy string `json:"createBy" gorm:"create_by"` // 创建者 - CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间 - StubType string `json:"stubType" gorm:"stub_type"` // 存根数据类型 0系统 1班级 2个人 - NeType string `json:"neType" gorm:"ne_type"` // 网元类型 - ParamName string `json:"paramName" gorm:"param_name"` // 参数名 - ParamDisplay string `json:"paramDisplay" gorm:"param_display"` // 参数显示名 - ParamType string `json:"paramType" gorm:"param_type"` // 参数类型 list列表单层 array数组多层 - ParamJsonOld string `json:"paramJsonOld" gorm:"param_json_old"` // 原始内容 - ParamJsonNew string `json:"paramJsonNew" gorm:"param_json_new"` // 当前内容 - OperaType int64 `json:"operaType" gorm:"opera_type"` // 操作类型 0其他 1新增 2更新 3删除 + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // ID + CreateBy string `json:"createBy" gorm:"create_by"` // 创建者 + CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间 + StubType string `json:"stubType" gorm:"stub_type"` // 存根数据类型 0系统 1班级 2个人 + NeType string `json:"neType" gorm:"ne_type"` // 网元类型 + ParamName string `json:"paramName" gorm:"param_name"` // 参数名 + ParamDisplay string `json:"paramDisplay" gorm:"param_display"` // 参数显示名 + ParamType string `json:"paramType" gorm:"param_type"` // 参数类型 list列表单层 array数组多层 + ParamJsonOld string `json:"paramJsonOld" gorm:"param_json_old"` // 原始内容 + ParamJsonNew string `json:"paramJsonNew" gorm:"param_json_new"` // 当前内容 + OperaType int64 `json:"operaType" gorm:"opera_type"` // 操作类型 0其他 1新增 2更新 3删除 } // TableName 表名称 diff --git a/src/modules/practical_training/service/pt_ne_config_data.go b/src/modules/practical_training/service/pt_ne_config_data.go index 386b46be..6574092a 100644 --- a/src/modules/practical_training/service/pt_ne_config_data.go +++ b/src/modules/practical_training/service/pt_ne_config_data.go @@ -33,4 +33,7 @@ type IPtNeConfigDataService interface { // SelectByStubType 通过存根类型查询 SelectByStubType(param model.PtNeConfigData) model.PtNeConfigData + + // ApplyToNe 参数应用到网元 + ApplyToNe(paramUser, neType string) error } diff --git a/src/modules/practical_training/service/pt_ne_config_data.impl.go b/src/modules/practical_training/service/pt_ne_config_data.impl.go index da3bb6d1..d86f2c6f 100644 --- a/src/modules/practical_training/service/pt_ne_config_data.impl.go +++ b/src/modules/practical_training/service/pt_ne_config_data.impl.go @@ -93,10 +93,11 @@ func (r *PtNeConfigDataService) SaveAsDefaultByType(neInfo neModel.NeInfo, stubT continue } // 将json数据转字符串存储 data:[{},{}] - if _, ok := resData["data"]; !ok { + data, ok := resData["data"] + if !ok { continue } - paramDataByte, err := json.Marshal(resData) + paramDataByte, err := json.Marshal(data) if err != nil { continue } @@ -129,6 +130,7 @@ func (r *PtNeConfigDataService) ResetAsDefaultByType(neType, stubType, operaUser for _, v := range ptConfs { // 查询是否存在记录 hasItems := r.SelectList(model.PtNeConfigData{ + CreateBy: operaUserName, NeType: v.NeType, StubType: stubType, ParamName: v.ParamName, @@ -175,8 +177,42 @@ func (r *PtNeConfigDataService) SelectByStubType(param model.PtNeConfigData) mod if len(list) > 0 { paraData = list[0] if err := json.Unmarshal([]byte(paraData.ParamJson), ¶Data.ParamData); err != nil { - paraData.ParamData = map[string]any{} + paraData.ParamData = []map[string]any{} } } return paraData } + +// ApplyToNe 参数应用到网元 +func (r *PtNeConfigDataService) ApplyToNe(paramUser, neType string) error { + ptConfs := r.SelectList(model.PtNeConfigData{CreateBy: paramUser, StubType: "2", NeType: neType}) + if len(ptConfs) == 0 { + return fmt.Errorf("NeConfigData Not Found") + } + + // 找网元,只有一套就固定001 + neInfo := r.neInfoService.SelectNeInfoByNeTypeAndNeID(neType, "001") + if neInfo.NeType != neType || neInfo.ID == "" { + return fmt.Errorf("NeInfo Not Found") + } + + // 遍历去设置参数 + for _, ptConf := range ptConfs { + if err := json.Unmarshal([]byte(ptConf.ParamJson), &ptConf.ParamData); err != nil { + ptConf.ParamData = []map[string]any{} + } + // 将json数据转字符串存储 [{},{}] + if len(ptConf.ParamData) == 0 { + continue + } + + if ptConf.ParamType == "list" { + dataMap := ptConf.ParamData[0] + for k, v := range dataMap { + fmt.Println(k, v) + } + } + } + + return nil +}