fix: 实训参数配置修改功能接口支持array层级

This commit is contained in:
TsMask
2024-07-05 15:58:09 +08:00
parent 5d504b5ec7
commit 94ce2c735e
5 changed files with 188 additions and 100 deletions

View File

@@ -2,6 +2,7 @@ package controller
import ( import (
"encoding/json" "encoding/json"
"strings"
"be.ems/src/framework/i18n" "be.ems/src/framework/i18n"
"be.ems/src/framework/utils/ctx" "be.ems/src/framework/utils/ctx"
@@ -76,23 +77,14 @@ func (s *PtNeConfigDataController) ResetAsDefault(c *gin.Context) {
language := ctx.AcceptLanguage(c) language := ctx.AcceptLanguage(c)
var body struct { var body struct {
NeType string `json:"neType" binding:"required"` // 网元类型 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.ShouldBindBodyWith(&body, binding.JSON); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return return
} }
stubType := "" // 存根数据类型 0系统 1班级 2个人 stubType := "2" // 存根数据类型 0系统 1班级 2个人
loginUser, _ := ctx.LoginUser(c) operaUserName := ctx.LoginUserToUserName(c)
for _, v := range loginUser.User.Roles {
if v.RoleKey == "student" {
stubType = "2"
} else if v.RoleKey == "teacher" {
stubType = "1"
}
}
operaUserName := loginUser.User.NickName
s.ptNeConfigDataService.ResetAsDefaultByType(body.NeType, stubType, operaUserName) s.ptNeConfigDataService.ResetAsDefaultByType(body.NeType, stubType, operaUserName)
c.JSON(200, result.Ok(nil)) c.JSON(200, result.Ok(nil))
@@ -114,6 +106,7 @@ func (s *PtNeConfigDataController) Info(c *gin.Context) {
// 优先查询个人的数据,没有就向系统取 // 优先查询个人的数据,没有就向系统取
param := model.PtNeConfigData{ param := model.PtNeConfigData{
CreateBy: ctx.LoginUserToUserName(c),
NeType: querys.NeType, NeType: querys.NeType,
StubType: "2", StubType: "2",
ParamName: querys.ParamName, ParamName: querys.ParamName,
@@ -122,9 +115,10 @@ func (s *PtNeConfigDataController) Info(c *gin.Context) {
// 输出数据内容 // 输出数据内容
if info.ParamJson != "" { if info.ParamJson != "" {
data := info.ParamData c.JSON(200, result.Ok(map[string]any{
data["paramType"] = info.ParamType "paramType": info.ParamType,
c.JSON(200, result.Ok(data)) "paramData": info.ParamData,
}))
return return
} }
c.JSON(200, result.Err(nil)) c.JSON(200, result.Err(nil))
@@ -135,7 +129,12 @@ func (s *PtNeConfigDataController) Info(c *gin.Context) {
// PUT / // PUT /
func (s *PtNeConfigDataController) Edit(c *gin.Context) { func (s *PtNeConfigDataController) Edit(c *gin.Context) {
language := ctx.AcceptLanguage(c) 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 { if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return return
@@ -150,11 +149,6 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) {
ParamName: body.ParamName, ParamName: body.ParamName,
} }
info := s.ptNeConfigDataService.SelectByStubType(param) 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{ changeLog := model.PtNeConfigDataLog{
CreateBy: currentUserName, CreateBy: currentUserName,
StubType: info.StubType, StubType: info.StubType,
@@ -163,35 +157,56 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) {
ParamDisplay: info.ParamDisplay, ParamDisplay: info.ParamDisplay,
ParamType: info.ParamType, ParamType: info.ParamType,
OperaType: 2, OperaType: 2,
ParamJsonOld: info.ParamJson,
} }
// 修改的属性 // 单层修改的属性
if infoDataArr, ok := info.ParamData["data"]; ok { if info.ParamType == "list" && len(info.ParamData) == 1 {
arr := infoDataArr.([]any) for k, v := range body.ParamData {
// 单层 item := info.ParamData[0]
if info.ParamType == "list" && len(arr) == 1 { if _, ok := item[k]; ok {
for k, v := range body.ParamData { item[k] = v
item := arr[0].(map[string]any)
if _, ok := item[k]; ok {
item[k] = v
arr[0] = item
}
} }
info.ParamData[0] = item
} }
// 多层 }
if info.ParamType == "array" { // 多层修改的属性
if len(arr) == 0 { if info.ParamType == "array" {
arr = []any{body.ParamData} if body.Loc == "" {
} else { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
idx := parse.Number(idx) return
if idx < 0 || int(idx) >= len(arr) { }
c.JSON(400, result.CodeMsg(400, "index over data step")) // 检查层级
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 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数据转字符串存储 // 将json数据转字符串存储
@@ -200,7 +215,6 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) {
c.JSON(400, result.CodeMsg(400, err.Error())) c.JSON(400, result.CodeMsg(400, err.Error()))
return return
} }
changeLog.ParamJsonOld = info.ParamJson
info.ParamJson = string(paramDataByte) info.ParamJson = string(paramDataByte)
changeLog.ParamJsonNew = info.ParamJson changeLog.ParamJsonNew = info.ParamJson
@@ -230,7 +244,12 @@ func (s *PtNeConfigDataController) Edit(c *gin.Context) {
// POST / // POST /
func (s *PtNeConfigDataController) Add(c *gin.Context) { func (s *PtNeConfigDataController) Add(c *gin.Context) {
language := ctx.AcceptLanguage(c) 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 { if err := c.ShouldBindBodyWith(&body, binding.JSON); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return return
@@ -245,13 +264,15 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) {
ParamName: body.ParamName, ParamName: body.ParamName,
} }
info := s.ptNeConfigDataService.SelectByStubType(param) info := s.ptNeConfigDataService.SelectByStubType(param)
if info.ParamType != "array" { if info.ParamType != "array" || body.Loc == "" {
c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return return
} }
idx, idxOk := body.ParamData["index"] // 检查层级
if info.ParamType == "array" && !idxOk { locArr := strings.Split(body.Loc, "/")
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) loc := parse.Number(locArr[0])
if loc < 0 || int(loc) < len(info.ParamData) {
c.JSON(400, result.CodeMsg(400, "loc less data step"))
return return
} }
changeLog := model.PtNeConfigDataLog{ changeLog := model.PtNeConfigDataLog{
@@ -262,24 +283,28 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) {
ParamDisplay: info.ParamDisplay, ParamDisplay: info.ParamDisplay,
ParamType: info.ParamType, ParamType: info.ParamType,
OperaType: 1, OperaType: 1,
ParamJsonOld: info.ParamJson,
} }
// 要修改的属性 // 要新增的属性
if infoDataArr, ok := info.ParamData["data"]; ok { if len(locArr) == 1 {
arr := infoDataArr.([]any) body.ParamData["index"] = len(info.ParamData)
if len(arr) == 0 { info.ParamData = append(info.ParamData, body.ParamData)
body.ParamData["index"] = 0 }
arr = []any{body.ParamData} if len(locArr) > 2 {
} else { item := info.ParamData[loc]
idx := parse.Number(idx) if a, ok := item[locArr[1]]; ok {
if idx < 0 || int(idx) < len(arr) { arr := a.([]any)
c.JSON(400, result.CodeMsg(400, "index less than data step")) 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 return
} }
body.ParamData["index"] = len(arr) body.ParamData["index"] = len(arr)
arr = append(arr, body.ParamData) arr = append(arr, body.ParamData)
item[locArr[1]] = arr
} }
info.ParamData["data"] = arr info.ParamData[loc] = item
} }
// 将json数据转字符串存储 // 将json数据转字符串存储
@@ -288,7 +313,6 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) {
c.JSON(400, result.CodeMsg(400, err.Error())) c.JSON(400, result.CodeMsg(400, err.Error()))
return return
} }
changeLog.ParamJsonOld = info.ParamJson
info.ParamJson = string(paramDataByte) info.ParamJson = string(paramDataByte)
changeLog.ParamJsonNew = info.ParamJson changeLog.ParamJsonNew = info.ParamJson
@@ -319,9 +343,9 @@ func (s *PtNeConfigDataController) Add(c *gin.Context) {
func (s *PtNeConfigDataController) Remove(c *gin.Context) { func (s *PtNeConfigDataController) Remove(c *gin.Context) {
language := ctx.AcceptLanguage(c) language := ctx.AcceptLanguage(c)
var query struct { var query struct {
Index int64 `form:"index" binding:"required"` //定位变更数据项 NeType string `form:"neType" binding:"required"` // 网元类型
NeType string `form:"neType" binding:"required"` // 网元类型 ParamName string `form:"paramName" 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 { if err := c.ShouldBindQuery(&query); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) 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, ParamName: query.ParamName,
} }
info := s.ptNeConfigDataService.SelectByStubType(param) info := s.ptNeConfigDataService.SelectByStubType(param)
if info.ParamType != "array" { if info.ParamType != "array" || query.Loc == "" {
c.JSON(400, result.CodeMsg(400, "this attribute does not support adding")) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return 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{ changeLog := model.PtNeConfigDataLog{
CreateBy: currentUserName, CreateBy: currentUserName,
StubType: info.StubType, StubType: info.StubType,
@@ -349,29 +381,25 @@ func (s *PtNeConfigDataController) Remove(c *gin.Context) {
ParamDisplay: info.ParamDisplay, ParamDisplay: info.ParamDisplay,
ParamType: info.ParamType, ParamType: info.ParamType,
OperaType: 3, OperaType: 3,
ParamJsonOld: info.ParamJson,
} }
// 要修改的属性 // 要删除的属性
if infoDataArr, ok := info.ParamData["data"]; ok { if len(locArr) == 1 {
arr := infoDataArr.([]any) info.ParamData = append(info.ParamData[:loc], info.ParamData[loc+1:]...)
if len(arr) == 0 { }
c.JSON(400, result.CodeMsg(400, "index over data step")) if len(locArr) > 2 {
return item := info.ParamData[loc]
} else { if a, ok := item[locArr[1]]; ok {
idx := parse.Number(query.Index) arr := a.([]any)
if idx < 0 || int(idx) >= len(arr) { aLoc := parse.Number(locArr[2])
c.JSON(400, result.CodeMsg(400, "index over data step")) if aLoc < 0 || int(aLoc) >= len(arr) {
c.JSON(400, result.CodeMsg(400, locArr[1]+" loc over data step"))
return return
} }
// 删除后重排index序号 item[locArr[1]] = append(arr[:aLoc], arr[aLoc+1:]...)
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 info.ParamData[loc] = item
} }
// 将json数据转字符串存储 // 将json数据转字符串存储
@@ -380,9 +408,30 @@ func (s *PtNeConfigDataController) Remove(c *gin.Context) {
c.JSON(400, result.CodeMsg(400, err.Error())) c.JSON(400, result.CodeMsg(400, err.Error()))
return 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) info.ParamJson = string(paramDataByte)
changeLog.ParamJsonNew = info.ParamJson
// 个人有数据就更新 // 个人有数据就更新
if info.StubType == "2" { if info.StubType == "2" {

View File

@@ -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 表名称 // TableName 表名称

View File

@@ -2,17 +2,17 @@ package model
// PtNeConfigDataLog 实训教学_网元参数配置数据变更日志 // PtNeConfigDataLog 实训教学_网元参数配置数据变更日志
type PtNeConfigDataLog struct { type PtNeConfigDataLog struct {
ID string `json:"id" gorm:"id"` // ID ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // ID
CreateBy string `json:"createBy" gorm:"create_by"` // 创建者 CreateBy string `json:"createBy" gorm:"create_by"` // 创建者
CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间 CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间
StubType string `json:"stubType" gorm:"stub_type"` // 存根数据类型 0系统 1班级 2个人 StubType string `json:"stubType" gorm:"stub_type"` // 存根数据类型 0系统 1班级 2个人
NeType string `json:"neType" gorm:"ne_type"` // 网元类型 NeType string `json:"neType" gorm:"ne_type"` // 网元类型
ParamName string `json:"paramName" gorm:"param_name"` // 参数名 ParamName string `json:"paramName" gorm:"param_name"` // 参数名
ParamDisplay string `json:"paramDisplay" gorm:"param_display"` // 参数显示名 ParamDisplay string `json:"paramDisplay" gorm:"param_display"` // 参数显示名
ParamType string `json:"paramType" gorm:"param_type"` // 参数类型 list列表单层 array数组多层 ParamType string `json:"paramType" gorm:"param_type"` // 参数类型 list列表单层 array数组多层
ParamJsonOld string `json:"paramJsonOld" gorm:"param_json_old"` // 原始内容 ParamJsonOld string `json:"paramJsonOld" gorm:"param_json_old"` // 原始内容
ParamJsonNew string `json:"paramJsonNew" gorm:"param_json_new"` // 当前内容 ParamJsonNew string `json:"paramJsonNew" gorm:"param_json_new"` // 当前内容
OperaType int64 `json:"operaType" gorm:"opera_type"` // 操作类型 0其他 1新增 2更新 3删除 OperaType int64 `json:"operaType" gorm:"opera_type"` // 操作类型 0其他 1新增 2更新 3删除
} }
// TableName 表名称 // TableName 表名称

View File

@@ -33,4 +33,7 @@ type IPtNeConfigDataService interface {
// SelectByStubType 通过存根类型查询 // SelectByStubType 通过存根类型查询
SelectByStubType(param model.PtNeConfigData) model.PtNeConfigData SelectByStubType(param model.PtNeConfigData) model.PtNeConfigData
// ApplyToNe 参数应用到网元
ApplyToNe(paramUser, neType string) error
} }

View File

@@ -93,10 +93,11 @@ func (r *PtNeConfigDataService) SaveAsDefaultByType(neInfo neModel.NeInfo, stubT
continue continue
} }
// 将json数据转字符串存储 data:[{},{}] // 将json数据转字符串存储 data:[{},{}]
if _, ok := resData["data"]; !ok { data, ok := resData["data"]
if !ok {
continue continue
} }
paramDataByte, err := json.Marshal(resData) paramDataByte, err := json.Marshal(data)
if err != nil { if err != nil {
continue continue
} }
@@ -129,6 +130,7 @@ func (r *PtNeConfigDataService) ResetAsDefaultByType(neType, stubType, operaUser
for _, v := range ptConfs { for _, v := range ptConfs {
// 查询是否存在记录 // 查询是否存在记录
hasItems := r.SelectList(model.PtNeConfigData{ hasItems := r.SelectList(model.PtNeConfigData{
CreateBy: operaUserName,
NeType: v.NeType, NeType: v.NeType,
StubType: stubType, StubType: stubType,
ParamName: v.ParamName, ParamName: v.ParamName,
@@ -175,8 +177,42 @@ func (r *PtNeConfigDataService) SelectByStubType(param model.PtNeConfigData) mod
if len(list) > 0 { if len(list) > 0 {
paraData = list[0] paraData = list[0]
if err := json.Unmarshal([]byte(paraData.ParamJson), &paraData.ParamData); err != nil { if err := json.Unmarshal([]byte(paraData.ParamJson), &paraData.ParamData); err != nil {
paraData.ParamData = map[string]any{} paraData.ParamData = []map[string]any{}
} }
} }
return paraData 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
}