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 7dbb9f2e..fa65c898 100644 --- a/src/modules/practical_training/controller/pt_ne_config_data.go +++ b/src/modules/practical_training/controller/pt_ne_config_data.go @@ -2,7 +2,6 @@ package controller import ( "encoding/json" - "strings" "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" @@ -34,6 +33,42 @@ type PtNeConfigData struct { neInfoService neService.INeInfo } +// 保存为示例配置 (仅管理员/教师操作) +// +// POST /saveAsDefault +func (s *PtNeConfigData) SaveAsDefault(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 + } + + // 查询网元获取IP获取网元状态 + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) + if neInfo.NeId != body.NeId || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + stubType := "" // 存根数据类型 0系统 1班级 2个人 + loginUser, _ := ctx.LoginUser(c) + for _, v := range loginUser.User.Roles { + if v.RoleName == "admin" { + stubType = "0" + } else if v.RoleName == "teacher" { + stubType = "1" + } + } + operaUserName := loginUser.User.NickName + s.ptNeConfigDataService.SaveAsDefaultByType(neInfo, stubType, operaUserName) + + c.JSON(200, result.Ok(nil)) +} + // 网元参数配置信息 // // GET / @@ -66,7 +101,7 @@ func (s *PtNeConfigData) Info(c *gin.Context) { c.JSON(200, result.Err(nil)) } -// 网元参数配置新增 +// 网元参数配置新增(array) // // POST / func (s *PtNeConfigData) Add(c *gin.Context) { @@ -86,8 +121,42 @@ func (s *PtNeConfigData) 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")) + return + } + 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, + NeType: info.NeType, + ParamName: info.ParamName, + ParamDisplay: info.ParamDisplay, + ParamType: info.ParamType, + OperaType: 1, + } // 要修改的属性 + 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")) + return + } + body.ParamData["index"] = len(arr) + arr = append(arr, body.ParamData) + } + info.ParamData["data"] = arr + } // 将json数据转字符串存储 paramDataByte, err := json.Marshal(info.ParamData) @@ -95,9 +164,11 @@ func (s *PtNeConfigData) 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 - // 个人没数据要新增 + // 个人有数据就更新 if info.StubType == "2" { info.UpdateBy = currentUserName s.ptNeConfigDataService.Update(info) @@ -108,16 +179,19 @@ func (s *PtNeConfigData) Add(c *gin.Context) { StubType: "2", ParamName: info.ParamName, ParamDisplay: info.ParamDisplay, + ParamType: info.ParamType, ParamJson: info.ParamJson, }) } + // 保留变更日志 + s.ptNeConfigDataLogService.Insert(changeLog) - c.JSON(204, nil) + c.JSON(200, result.OkData(body.ParamData)) } // 网元参数配置修改 // -// PUT /?loc=1 +// PUT / func (s *PtNeConfigData) Edit(c *gin.Context) { language := ctx.AcceptLanguage(c) var body model.PtNeConfigData @@ -135,8 +209,8 @@ func (s *PtNeConfigData) Edit(c *gin.Context) { ParamName: body.ParamName, } info := s.ptNeConfigDataService.SelectByStubType(param) - loc, locOk := c.GetQuery("loc") - if info.ParamType == "array" && !locOk { + idx, idxOk := body.ParamData["index"] + if info.ParamType == "array" && !idxOk { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } @@ -147,6 +221,7 @@ func (s *PtNeConfigData) Edit(c *gin.Context) { ParamName: info.ParamName, ParamDisplay: info.ParamDisplay, ParamType: info.ParamType, + OperaType: 2, } // 要修改的属性 @@ -167,9 +242,9 @@ func (s *PtNeConfigData) Edit(c *gin.Context) { if len(arr) == 0 { arr = []any{body.ParamData} } else { - idx := parse.Number(loc) + idx := parse.Number(idx) if idx < 0 || int(idx) >= len(arr) { - c.JSON(400, result.CodeMsg(400, "loc over data step")) + c.JSON(400, result.CodeMsg(400, "index over data step")) return } arr[idx] = body.ParamData @@ -209,64 +284,94 @@ func (s *PtNeConfigData) Edit(c *gin.Context) { c.JSON(204, nil) } -// 网元参数配置删除 +// 网元参数配置删除(array) // -// DELETE /:ids +// DELETE / func (s *PtNeConfigData) Remove(c *gin.Context) { language := ctx.AcceptLanguage(c) - ids := c.Param("ids") - if ids == "" { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) - return + var query struct { + Index int64 `form:"index" binding:"required"` //定位变更数据项 + NeType string `form:"neType" binding:"required"` // 网元类型 + ParamName string `form:"paramName" binding:"required"` // 根据配置可选值 } - // 处理字符转id数组后去重 - idsArr := strings.Split(ids, ",") - uniqueIDs := parse.RemoveDuplicates(idsArr) - if len(uniqueIDs) <= 0 { - c.JSON(200, result.Err(nil)) - return - } - rows, err := s.ptNeConfigDataService.DeleteByIds(uniqueIDs) - if err != nil { - c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) - return - } - msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) - c.JSON(200, result.OkMsg(msg)) -} - -// 保存为示例配置 (仅管理员/教师操作) -// -// POST /saveAsDefault -func (s *PtNeConfigData) SaveAsDefault(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 { + if err := c.ShouldBindQuery(&query); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } - // 查询网元获取IP获取网元状态 - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) - if neInfo.NeId != body.NeId || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + currentUserName := ctx.LoginUserToUserName(c) + // 优先查询个人的数据,没有就向系统取 + param := model.PtNeConfigData{ + CreateBy: currentUserName, + NeType: query.NeType, + StubType: "2", + ParamName: query.ParamName, + } + info := s.ptNeConfigDataService.SelectByStubType(param) + if info.ParamType != "array" { + c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) return } + changeLog := model.PtNeConfigDataLog{ + CreateBy: currentUserName, + StubType: info.StubType, + NeType: info.NeType, + ParamName: info.ParamName, + ParamDisplay: info.ParamDisplay, + ParamType: info.ParamType, + OperaType: 3, + } - stubType := "" // 存根数据类型 0系统 1班级 2个人 - loginUser, _ := ctx.LoginUser(c) - for _, v := range loginUser.User.Roles { - if v.RoleName == "admin" { - stubType = "0" - } else if v.RoleName == "teacher" { - stubType = "1" + // 要修改的属性 + 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")) + 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 + } } + info.ParamData["data"] = arr } - operaUserName := loginUser.User.NickName - s.ptNeConfigDataService.SaveAsDefaultByType(neInfo, stubType, operaUserName) - c.JSON(200, result.Ok(nil)) + // 将json数据转字符串存储 + paramDataByte, err := json.Marshal(info.ParamData) + if err != nil { + c.JSON(400, result.CodeMsg(400, err.Error())) + return + } + changeLog.ParamJsonOld = info.ParamJson + info.ParamJson = string(paramDataByte) + changeLog.ParamJsonNew = info.ParamJson + + // 个人有数据就更新 + if info.StubType == "2" { + info.UpdateBy = currentUserName + s.ptNeConfigDataService.Update(info) + } else { + s.ptNeConfigDataService.Insert(model.PtNeConfigData{ + CreateBy: currentUserName, + NeType: info.NeType, + StubType: "2", + ParamName: info.ParamName, + ParamDisplay: info.ParamDisplay, + ParamType: info.ParamType, + ParamJson: info.ParamJson, + }) + } + // 保留变更日志 + s.ptNeConfigDataLogService.Insert(changeLog) + + c.JSON(204, nil) } 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 003abfd1..785f5253 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 @@ -12,6 +12,7 @@ type PtNeConfigDataLog struct { 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/practical_training.go b/src/modules/practical_training/practical_training.go index 4f15448a..ca12afb4 100644 --- a/src/modules/practical_training/practical_training.go +++ b/src/modules/practical_training/practical_training.go @@ -18,6 +18,11 @@ func Setup(router *gin.Engine) { // 网元参数配置 paramConfigGroup := ptGroup.Group("/neConfigData") { + paramConfigGroup.POST("/saveAsDefault", + middleware.PreAuthorize(map[string][]string{"hasRoles": {"admin", "teacher"}}), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigData", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewPtNeConfigData.SaveAsDefault, + ) paramConfigGroup.GET("", middleware.PreAuthorize(nil), controller.NewPtNeConfigData.Info, @@ -32,16 +37,11 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigData", collectlogs.BUSINESS_TYPE_UPDATE)), controller.NewPtNeConfigData.Edit, ) - paramConfigGroup.DELETE("/:ids", + paramConfigGroup.DELETE("/", middleware.PreAuthorize(nil), collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigData", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewPtNeConfigData.Remove, ) - paramConfigGroup.POST("/saveAsDefault", - middleware.PreAuthorize(map[string][]string{"hasRoles": {"admin", "teacher"}}), - collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigData", collectlogs.BUSINESS_TYPE_OTHER)), - controller.NewPtNeConfigData.SaveAsDefault, - ) } // 网元参数配置数据变更日志 @@ -52,7 +52,7 @@ func Setup(router *gin.Engine) { controller.NewPtNeConfigDataLog.Info, ) paramConfigLogGroup.DELETE("/:ids", - middleware.PreAuthorize(nil), + middleware.PreAuthorize(map[string][]string{"hasRoles": {"admin"}}), collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neConfigDataLog", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewPtNeConfigDataLog.Remove, ) diff --git a/src/modules/practical_training/repository/pt_ne_config_data_log.impl.go b/src/modules/practical_training/repository/pt_ne_config_data_log.impl.go index 6baa9ba6..f1848635 100644 --- a/src/modules/practical_training/repository/pt_ne_config_data_log.impl.go +++ b/src/modules/practical_training/repository/pt_ne_config_data_log.impl.go @@ -14,7 +14,7 @@ import ( // NewPtNeConfigDataLogRepository 实例化数据层 var NewPtNeConfigDataLogRepository = &PtNeConfigDataLogRepository{ selectSql: `select - id, create_by, create_time, stub_type, ne_type, param_name, param_display, param_type, param_json_old, param_json_new + id, create_by, create_time, stub_type, ne_type, param_name, param_display, param_type, param_json_old, param_json_new, opera_type from pt_ne_config_data_log`, resultMap: map[string]string{ @@ -28,6 +28,7 @@ var NewPtNeConfigDataLogRepository = &PtNeConfigDataLogRepository{ "param_type": "ParamType", "param_json_old": "ParamJsonOld", "param_json_new": "ParamJsonNew", + "opera_type": "OperaType", }, } @@ -71,6 +72,10 @@ func (r *PtNeConfigDataLogRepository) SelectPage(query map[string]any) map[strin conditions = append(conditions, "param_type = ?") params = append(params, v) } + if v, ok := query["operaType"]; ok && v != "" { + conditions = append(conditions, "opera_type = ?") + params = append(params, v) + } // 构建查询条件语句 whereSql := "" @@ -141,6 +146,10 @@ func (r *PtNeConfigDataLogRepository) SelectList(param model.PtNeConfigDataLog) conditions = append(conditions, "param_type = ?") params = append(params, param.ParamType) } + if param.OperaType >= 0 { + conditions = append(conditions, "opera_type = ?") + params = append(params, param.OperaType) + } // 构建查询条件语句 whereSql := "" @@ -202,6 +211,7 @@ func (r *PtNeConfigDataLogRepository) Insert(param model.PtNeConfigDataLog) stri if param.ParamJsonNew != "" { params["param_json_new"] = param.ParamJsonNew } + params["opera_type"] = param.OperaType // 构建执行语句 keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)