package data import ( "errors" "eta/eta_api/models/data_manage" "eta/eta_api/models/system" "eta/eta_api/services/data/data_manage_permission" "eta/eta_api/utils" "fmt" "strconv" "time" ) func chartClassifyHaveChild(allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems) (childs []*data_manage.ChartClassifyItems, yes bool) { for _, v := range allNode { if v.ParentId == node.ChartClassifyId { childs = append(childs, v) } } if len(childs) > 0 { yes = true } return } func ChartClassifyItemsMakeTree(sysUser *system.Admin, allNode []*data_manage.ChartClassifyItems, node *data_manage.ChartClassifyItems, permissionClassifyIdList []int, level int) { node.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(node.IsJoinPermission, node.ChartClassifyId, permissionClassifyIdList) button := GetChartClassifyOpButton(sysUser, node.SysUserId, node.HaveOperaAuth) node.Button = button node.Disable = true if node.Level == level { node.Disable = false } childs, _ := chartClassifyHaveChild(allNode, node) //判断节点是否有子节点并返回 if len(childs) > 0 { for _, child := range childs { child.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(child.IsJoinPermission, child.ChartClassifyId, permissionClassifyIdList) childButton := GetChartClassifyOpButton(sysUser, child.SysUserId, child.HaveOperaAuth) if child.Level == 6 { childButton.AddButton = false //第六级的话,默认图表都是没有添加按钮的 } child.Disable = true if child.Level == level { child.Disable = false } child.Button = childButton //node.Children = append(node.Children, child) } node.Children = append(node.Children, childs[0:]...) //添加子节点 for _, v := range childs { v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ChartClassifyId, permissionClassifyIdList) //查询子节点的子节点,并添加到子节点 _, has := chartClassifyHaveChild(allNode, v) if has { ChartClassifyItemsMakeTree(sysUser, allNode, v, permissionClassifyIdList, level) //递归添加节点 } else { if level > 0 { v.Children = nil } else { childrenArr := make([]*data_manage.ChartClassifyItems, 0) v.Children = childrenArr } } } } else { if level > 0 { node.Children = nil } else { childrenArr := make([]*data_manage.ChartClassifyItems, 0) node.Children = childrenArr } } } func FixChartClassify() { //新增三级分类 list, err := data_manage.GetChartClassifyByLevel(2, 1) if err != nil { return } for _, v := range list { classify := new(data_manage.ChartClassify) classify.ParentId = v.ChartClassifyId classify.ChartClassifyName = v.ChartClassifyName classify.HasData = 0 classify.CreateTime = time.Now() classify.ModifyTime = time.Now() if utils.RunMode == "debug" { classify.SysUserId = 11 } else { classify.SysUserId = 163 } classify.SysUserRealName = "admin" classify.Level = 3 timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) classify.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp) classify.Sort = v.Sort classify.Source = utils.CHART_SOURCE_DEFAULT id, err := data_manage.AddChartClassify(classify) if err != nil { return } err = data_manage.FIXChartClassifyId(int(id), v.ChartClassifyId) if err != nil { return } } } func FixChartClassifySysUserId() { //获取所有父级分类信息 list, err := data_manage.GetChartClassifyByLevel(2, 1) if err != nil { return } for _, v := range list { err := data_manage.EditChartClassifySysUser(v.ChartClassifyId, v.SysUserId, v.SysUserRealName) if err != nil { return } fmt.Println("ChartClassifyId:", v.ChartClassifyId) } fmt.Println("FixChartClassifySysUserId end") } // GetChartClassifyOpButton 获取ETA图库分类的操作权限 func GetChartClassifyOpButton(sysUser *system.Admin, belongUserId int, haveOperaAuth bool) (button data_manage.ChartClassifyItemsButton) { // 没有数据权限就直接返回 if !haveOperaAuth { return } //ficc管理员和超管和ficc研究员有权限创建和管理分类,可以编辑分类名称(分类名称不允许重复),可以拖动分类,改变分类顺序,可以拖动分类下模型,改变顺序,可以删除分类,若分类下有预测指标,则不允许删除; //if utils.InArrayByStr([]string{utils.ROLE_TYPE_CODE_ADMIN, utils.ROLE_TYPE_CODE_FICC_ADMIN, utils.ROLE_TYPE_CODE_RESEARCHR, utils.ROLE_TYPE_CODE_FICC_RESEARCHR}, sysUser.RoleTypeCode) { button.AddButton = true button.OpButton = true button.DeleteButton = true button.MoveButton = true //} return } // GetCanOpChartClassify 获取是否允许添加图表分类 func GetCanOpChartClassify(roleTypeCode string) (canOpClassify bool) { // 如果不是 超管 或者 ficc管理员 或者 ficc研究员,那么就没有权限 if utils.InArrayByStr([]string{utils.ROLE_TYPE_CODE_ADMIN, utils.ROLE_TYPE_CODE_FICC_ADMIN, utils.ROLE_TYPE_CODE_RESEARCHR, utils.ROLE_TYPE_CODE_FICC_RESEARCHR}, roleTypeCode) { canOpClassify = true } return } // GetChartOpButton 获取ETA图库的操作权限 func GetChartOpButton(sysUser *system.Admin, belongUserId int, haveOperaAuth bool) (button data_manage.ChartClassifyItemsButton) { // 数据权限判断 if !haveOperaAuth { return } //预测指标的添加人对该预测指标有全部操作权限,ficc管理员、超管对所有预测指标有全部操作权限; if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN || sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_ADMIN || sysUser.AdminId == belongUserId || sysUser.PredictEdbPermission == 1 { button.AddButton = true button.OpButton = true button.DeleteButton = true button.MoveButton = true } return } // HandleNoPermissionChart 图表列表返回,将没有权限的图表移除 func HandleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool, sysUserId int) (newAllNodes []*data_manage.ChartClassifyItems) { // 涉及分类id classifyIdList := make([]int, 0) // 移除没有权限的图表 newAllNodes = make([]*data_manage.ChartClassifyItems, 0) for _, node := range allNodes { // 二级分类 tmpNodeInfo := *node tmpNodeList := make([]*data_manage.ChartClassifyItems, 0) if node.Children != nil { for _, chartInfo := range node.Children { // 如果指标不可见,那么就不返回该指标 if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok { continue } tmpNodeList = append(tmpNodeList, chartInfo) classifyIdList = append(classifyIdList, chartInfo.ChartClassifyId) } } tmpNodeInfo.Children = tmpNodeList newAllNodes = append(newAllNodes, &tmpNodeInfo) classifyIdList = append(classifyIdList, node.ChartClassifyId) } // 数据权限 if len(classifyIdList) > 0 { // 图表分类 chartClassifyList, err := data_manage.GetChartClassifyByIdList(classifyIdList) if err != nil { return } chartClassifyMap := make(map[int]*data_manage.ChartClassify) for _, v := range chartClassifyList { chartClassifyMap[v.ChartClassifyId] = v } // 已授权分类id permissionChartIdList, permissionClassifyIdList, err := data_manage_permission.GetUserChartAndClassifyPermissionList(sysUserId, 0, 0) if err != nil { return } for _, node := range newAllNodes { if node.Children != nil { for _, chartInfo := range node.Children { if currClassify, ok := chartClassifyMap[chartInfo.ChartClassifyId]; ok { chartInfo.HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(chartInfo.IsJoinPermission, currClassify.IsJoinPermission, chartInfo.ChartInfoId, chartInfo.ChartClassifyId, permissionChartIdList, permissionClassifyIdList) } } } if currClassify, ok := chartClassifyMap[node.ChartClassifyId]; ok { node.HaveOperaAuth = data_manage_permission.CheckChartPermissionByPermissionIdList(node.IsJoinPermission, currClassify.IsJoinPermission, node.ChartInfoId, node.ChartClassifyId, permissionChartIdList, permissionClassifyIdList) } } } return } // AddChartClassify // @Description: 添加图表分类 // @author: Roc // @datetime 2024-04-17 14:48:23 // @param chartClassifyName string // @param parentId int // @param level int // @param source int // @param lang string // @param sysUser *system.Admin // @return classifyInfo *data_manage.ChartClassify // @return err error // @return errMsg string // @return isSendEmail bool func AddChartClassify(chartClassifyName string, parentId, level, source int, lang string, sysUser *system.Admin) (classifyInfo *data_manage.ChartClassify, err error, errMsg string, isSendEmail bool) { isSendEmail = true errMsg = "保存分类失败" // 校验分类名称相同的数量 { var count int switch lang { case utils.EnLangVersion: count, err = data_manage.GetChartClassifyEnCount(chartClassifyName, parentId, source) default: count, err = data_manage.GetChartClassifyCount(chartClassifyName, parentId, source) } if err != nil { errMsg = "判断名称是否已存在失败" return } if count > 0 { errMsg = "分类名称已存在,请重新输入" err = errors.New(errMsg) isSendEmail = false return } } if level > 5 { errMsg = `最高只支持添加6级分类` return } //获取该层级下最大的排序数 maxSort, err := data_manage.GetChartClassifyMaxSort(parentId, source) if err != nil { errMsg = "获取失败" err = errors.New("查询排序信息失败,Err:" + err.Error()) return } //查询顶级rootId rootId := 0 if parentId > 0 { parentClassify, tErr := data_manage.GetChartClassifyById(parentId) if tErr != nil { if tErr.Error() == utils.ErrNoRow() { errMsg = "父级分类不存在" err = errors.New(errMsg) return } errMsg = "获取失败" err = errors.New("获取分类信息失败,Err:" + tErr.Error()) return } rootId = parentClassify.RootId } classifyInfo = new(data_manage.ChartClassify) classifyInfo.ParentId = parentId classifyInfo.ChartClassifyName = chartClassifyName classifyInfo.ChartClassifyNameEn = chartClassifyName classifyInfo.HasData = 0 classifyInfo.CreateTime = time.Now() classifyInfo.ModifyTime = time.Now() classifyInfo.SysUserId = sysUser.AdminId classifyInfo.SysUserRealName = sysUser.RealName classifyInfo.Level = level + 1 timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) classifyInfo.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp) classifyInfo.Sort = maxSort + 1 classifyInfo.Source = source classifyInfo.RootId = rootId newId, err := data_manage.AddChartClassify(classifyInfo) if err != nil { return } if parentId == 0 { //一级目录的rootId等于自己本身 classifyInfo.RootId = int(newId) err = classifyInfo.Update([]string{"RootId"}) if err != nil { errMsg = "更新分类失败" return } } // 目前只有ETA图库需要继承分类权限 if classifyInfo.Source == utils.CHART_SOURCE_DEFAULT { go data_manage_permission.InheritParentClassify(5, classifyInfo.Source, classifyInfo.ChartClassifyId, classifyInfo.ParentId, classifyInfo.ChartClassifyName) } return } // EditChartClassify // @Description: 修改图表分类 // @author: Roc // @datetime 2024-04-17 14:59:37 // @param chartClassifyId int // @param source int // @param chartClassifyName string // @param lang string // @param sysUser *system.Admin // @return classifyInfo *data_manage.ChartClassify // @return err error // @return errMsg string // @return isSendEmail bool func EditChartClassify(chartClassifyId, source int, chartClassifyName, lang string, sysUser *system.Admin) (classifyInfo *data_manage.ChartClassify, err error, errMsg string, isSendEmail bool) { isSendEmail = true errMsg = "保存失败" // 获取分类信息 classifyInfo, err = data_manage.GetChartClassifyById(chartClassifyId) if err != nil { return } // 分类来源校验 if classifyInfo.Source != source { errMsg = "图表分类异常" err = errors.New(fmt.Sprintf("图表分类来源异常,修改来源:%d,分类来源:%d", source, classifyInfo.Source)) isSendEmail = false return } // 需要变更的字段 updateCols := make([]string, 0) // 语言版本校验 switch lang { case utils.EnLangVersion: if classifyInfo.ChartClassifyNameEn != chartClassifyName { count, tmpErr := data_manage.GetChartClassifyEnCount(chartClassifyName, classifyInfo.ParentId, source) if tmpErr != nil { errMsg = "判断名称是否已存在失败" err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error()) return } if count > 0 { errMsg = "分类名称已存在,请重新输入" err = errors.New(errMsg) isSendEmail = false return } classifyInfo.ChartClassifyNameEn = chartClassifyName classifyInfo.ModifyTime = time.Now() updateCols = append(updateCols, "ChartClassifyNameEn", "ModifyTime") } default: if classifyInfo.ChartClassifyName != chartClassifyName { count, tmpErr := data_manage.GetChartClassifyCount(chartClassifyName, classifyInfo.ParentId, source) if tmpErr != nil { errMsg = "判断名称是否已存在失败" err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error()) return } if count > 0 { errMsg = "分类名称已存在,请重新输入" err = errors.New(errMsg) isSendEmail = false return } classifyInfo.ChartClassifyName = chartClassifyName classifyInfo.ModifyTime = time.Now() updateCols = append(updateCols, "ChartClassifyName", "ModifyTime") } } if len(updateCols) > 0 { err = classifyInfo.Update(updateCols) } return } // MoveChartClassify 移动图表分类 func MoveChartClassify(req data_manage.MoveChartClassifyReq, sysUser *system.Admin, source int) (err error, errMsg string) { classifyId := req.ClassifyId parentClassifyId := req.ParentClassifyId prevClassifyId := req.PrevClassifyId nextClassifyId := req.NextClassifyId chartInfoId := req.ChartInfoId prevChartInfoId := req.PrevChartInfoId nextChartInfoId := req.NextChartInfoId //首先确定移动的对象是分类还是指标 //判断上一个节点是分类还是指标 //判断下一个节点是分类还是指标 //同时更新分类目录下的分类sort和指标sort //更新当前移动的分类或者指标sort var parentChartClassifyInfo *data_manage.ChartClassify if parentClassifyId > 0 { parentChartClassifyInfo, err = data_manage.GetChartClassifyById(parentClassifyId) if err != nil { errMsg = "移动失败" err = errors.New("获取上级分类信息失败,Err:" + err.Error()) return } } //如果有传入 上一个兄弟节点分类id var ( chartClassifyInfo *data_manage.ChartClassify prevClassify *data_manage.ChartClassify nextClassify *data_manage.ChartClassify chartInfo *data_manage.ChartInfo prevChartInfo *data_manage.ChartInfo nextChartInfo *data_manage.ChartInfo prevSort int nextSort int ) // 移动对象为分类, 判断权限 if chartInfoId == 0 { chartClassifyInfo, err = data_manage.GetChartClassifyById(classifyId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前分类不存在" err = errors.New("获取分类信息失败,Err:" + err.Error()) return } errMsg = "移动失败" err = errors.New("获取分类信息失败,Err:" + err.Error()) return } if parentClassifyId > 0 && parentChartClassifyInfo.Level == 6 { errMsg = "最高只支持添加6级分类" err = errors.New(errMsg) return } // 如果是移动目录, 那么校验一下父级目录下是否有重名目录 exists, e := data_manage.GetChartClassifyByParentIdAndName(parentClassifyId, chartClassifyInfo.ChartClassifyName, classifyId) if e != nil && e.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = fmt.Errorf("获取父级分类下的同名分类失败, Err: %s", e.Error()) return } if exists != nil { errMsg = "移动失败,分类名称已存在" return } // 权限校验 { // 已授权分类id permissionClassifyIdList, tmpErr := data_manage_permission.GetUserChartClassifyPermissionList(sysUser.AdminId, classifyId) if tmpErr != nil { errMsg = "移动失败" err = errors.New("获取已授权分类id数据失败,Err:" + tmpErr.Error()) return } // 数据权限 haveOperaAuth := data_manage_permission.CheckChartClassifyPermissionByPermissionIdList(chartClassifyInfo.IsJoinPermission, chartClassifyInfo.ChartClassifyId, permissionClassifyIdList) button := GetChartClassifyOpButton(sysUser, chartClassifyInfo.SysUserId, haveOperaAuth) if !button.MoveButton { errMsg = "无操作权限" err = errors.New(errMsg) return } } } else { chartInfo, err = data_manage.GetChartInfoById(req.ChartInfoId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前图表不存在" err = errors.New("获取分类信息失败,Err:" + err.Error()) return } errMsg = "移动失败" err = errors.New("获取分类信息失败,Err:" + err.Error()) return } if parentClassifyId == 0 { errMsg = "移动失败,图表必须挂在分类下" err = errors.New(errMsg) return } var haveOperaAuth bool // 权限校验 { haveOperaAuth, err = data_manage_permission.CheckChartPermissionByChartInfoId(chartInfo.ChartInfoId, chartInfo.ChartClassifyId, chartInfo.IsJoinPermission, sysUser.AdminId) if err != nil { errMsg = "移动失败" err = errors.New("获取图表权限信息失败,Err:" + err.Error()) return } } // 移动权限校验 button := GetChartOpButton(sysUser, chartInfo.SysUserId, haveOperaAuth) if !button.MoveButton { errMsg = "无操作权限" err = errors.New(errMsg) return } } if prevClassifyId > 0 { prevClassify, err = data_manage.GetChartClassifyById(prevClassifyId) if err != nil { errMsg = "移动失败" err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error()) return } prevSort = prevClassify.Sort } else if prevChartInfoId > 0 { prevChartInfo, err = data_manage.GetChartInfoById(prevChartInfoId) if err != nil { errMsg = "移动失败" err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error()) return } prevSort = prevChartInfo.Sort } if nextClassifyId > 0 { //下一个兄弟节点 nextClassify, err = data_manage.GetChartClassifyById(nextClassifyId) if err != nil { errMsg = "移动失败" err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error()) return } nextSort = nextClassify.Sort } else if nextChartInfoId > 0 { //下一个兄弟节点 nextChartInfo, err = data_manage.GetChartInfoById(nextChartInfoId) if err != nil { errMsg = "移动失败" err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error()) return } nextSort = nextChartInfo.Sort } err, errMsg = moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify, chartInfo, prevChartInfo, nextChartInfo, parentClassifyId, prevSort, nextSort, source) return } // moveChartClassify 移动图表分类 func moveChartClassify(parentChartClassifyInfo, chartClassifyInfo, prevClassify, nextClassify *data_manage.ChartClassify, chartInfo, prevChartInfo, nextChartInfo *data_manage.ChartInfo, parentClassifyId, prevSort, nextSort, source int) (err error, errMsg string) { updateCol := make([]string, 0) // 移动对象为分类, 判断分类是否存在 if chartClassifyInfo != nil { oldParentId := chartClassifyInfo.ParentId oldLevel := chartClassifyInfo.Level var classifyIds []int if oldParentId != parentClassifyId { //更新子分类对应的level childList, e, m := GetChildChartClassifyByClassifyId(chartClassifyInfo.ChartClassifyId) if e != nil { errMsg = "移动失败" err = errors.New("查询子分类失败,Err:" + e.Error() + m) return } if len(childList) > 0 { for _, v := range childList { if v.ChartClassifyId == chartClassifyInfo.ChartClassifyId { continue } classifyIds = append(classifyIds, v.ChartClassifyId) } } } //判断上级id是否一致,如果不一致的话,那么需要移动该分类层级 if chartClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 { if chartClassifyInfo.Level != parentChartClassifyInfo.Level+1 { //禁止层级调整 errMsg = "移动失败" err = errors.New("不支持目录层级变更") return } chartClassifyInfo.ParentId = parentChartClassifyInfo.ChartClassifyId chartClassifyInfo.RootId = parentChartClassifyInfo.RootId chartClassifyInfo.Level = parentChartClassifyInfo.Level + 1 chartClassifyInfo.ModifyTime = time.Now() updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime") } else if chartClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 { errMsg = "移动失败" err = errors.New("不支持目录层级变更") return } if prevSort > 0 { //如果是移动在两个兄弟节点之间 if nextSort > 0 { //下一个兄弟节点 //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1 if prevSort == nextSort || prevSort == chartClassifyInfo.Sort { //变更兄弟节点的排序 updateSortStr := `sort + 2` //变更分类 if prevClassify != nil { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr, source) } else { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source) } //变更图表 if prevChartInfo != nil { //变更兄弟节点的排序 _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr) } else { _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr) } } else { //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了 if nextSort-prevSort == 1 { //变更兄弟节点的排序 updateSortStr := `sort + 1` //变更分类 if prevClassify != nil { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevSort, updateSortStr, source) } else { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source) } //变更图表 if prevChartInfo != nil { //变更兄弟节点的排序 _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr) } else { _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr) } } } } chartClassifyInfo.Sort = prevSort + 1 chartClassifyInfo.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else if prevClassify == nil && nextClassify == nil && prevChartInfo == nil && nextChartInfo == nil && parentClassifyId > 0 { //处理只拖动到目录里,默认放到目录底部的情况 var maxSort int maxSort, err = GetChartClassifyMaxSort(parentClassifyId, source) if err != nil { errMsg = "移动失败" err = errors.New("查询组内排序信息失败,Err:" + err.Error()) return } chartClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位 chartClassifyInfo.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else { // 拖动到父级分类的第一位 firstClassify, tmpErr := data_manage.GetFirstChartClassifyByParentId(parentClassifyId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error()) return } //如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序 if firstClassify != nil && firstClassify.Sort == 0 { updateSortStr := ` sort + 1 ` _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, firstClassify.ChartClassifyId-1, 0, updateSortStr, source) //该分类下的所有图表也需要+1 _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, 0, updateSortStr) } else { //如果该分类下存在图表,且第一个图表的排序等于0,那么需要调整排序 firstEdb, tErr := data_manage.GetFirstChartInfoByClassifyId(parentClassifyId) if tErr != nil && tErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error()) return } //如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序 if firstEdb != nil && firstEdb.Sort == 0 { updateSortStr := ` sort + 1 ` _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, firstEdb.ChartInfoId-1, updateSortStr) _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, 0, updateSortStr, source) } } chartClassifyInfo.Sort = 0 //那就是排在第一位 chartClassifyInfo.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } //更新 if len(updateCol) > 0 { err = chartClassifyInfo.Update(updateCol) if err != nil { errMsg = "移动失败" err = errors.New("修改失败,Err:" + err.Error()) return } //更新对应分类的root_id和层级 if oldParentId != parentClassifyId { if len(classifyIds) > 0 { levelStep := chartClassifyInfo.Level - oldLevel err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, chartClassifyInfo.RootId, levelStep) if err != nil { errMsg = "移动失败" err = errors.New("更新子分类失败,Err:" + err.Error()) return } } } } } else { if chartInfo == nil { errMsg = "当前图表不存在" err = errors.New(errMsg) return } //如果改变了分类,那么移动该图表数据 if chartInfo.ChartClassifyId != parentClassifyId { chartInfo.ChartClassifyId = parentClassifyId chartInfo.ModifyTime = time.Now() updateCol = append(updateCol, "ChartClassifyId", "ModifyTime") } if prevSort > 0 { //如果是移动在两个兄弟节点之间 if nextSort > 0 { //下一个兄弟节点 //如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1 if prevSort == nextSort || prevSort == chartInfo.Sort { //变更兄弟节点的排序 updateSortStr := `sort + 2` //变更分类 if prevClassify != nil { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevClassify.Sort, updateSortStr, source) } else { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source) } //变更图表 if prevChartInfo != nil { //变更兄弟节点的排序 _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr) } else { _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr) } } else { //如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了 if nextSort-prevSort == 1 { //变更兄弟节点的排序 updateSortStr := `sort + 1` //变更分类 if prevClassify != nil { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, prevClassify.ChartClassifyId, prevSort, updateSortStr, source) } else { _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, prevSort, updateSortStr, source) } //变更图表 if prevChartInfo != nil { //变更兄弟节点的排序 _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, prevChartInfo.ChartInfoId, updateSortStr) } else { _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, prevSort, 0, updateSortStr) } } } } chartInfo.Sort = prevSort + 1 chartInfo.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else if prevClassify == nil && nextClassify == nil && prevChartInfo == nil && nextChartInfo == nil && parentClassifyId > 0 { //处理只拖动到目录里,默认放到目录底部的情况 var maxSort int maxSort, err = GetChartClassifyMaxSort(parentClassifyId, source) if err != nil { errMsg = "移动失败" err = errors.New("查询组内排序信息失败,Err:" + err.Error()) return } chartInfo.Sort = maxSort + 1 //那就是排在组内最后一位 chartInfo.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } else { // 拖动到父级分类的第一位 firstClassify, tmpErr := data_manage.GetFirstChartClassifyByParentId(parentClassifyId) if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error()) return } //如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序 if firstClassify != nil && firstClassify.Sort == 0 { updateSortStr := ` sort + 1 ` _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, firstClassify.ChartClassifyId-1, 0, updateSortStr, source) //该分类下的所有图表也需要+1 _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, 0, updateSortStr) } else { //如果该分类下存在图表,且第一个图表的排序等于0,那么需要调整排序 firstEdb, tErr := data_manage.GetFirstChartInfoByClassifyId(parentClassifyId) if tErr != nil && tErr.Error() != utils.ErrNoRow() { errMsg = "移动失败" err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error()) return } //如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序 if firstEdb != nil && firstEdb.Sort == 0 { updateSortStr := ` sort + 1 ` _ = data_manage.UpdateChartInfoSortByClassifyIdV2(parentClassifyId, 0, firstEdb.ChartInfoId-1, updateSortStr) _ = data_manage.UpdateChartClassifySortByParentIdAndSource(parentClassifyId, 0, 0, updateSortStr, source) } } chartInfo.Sort = 0 //那就是排在第一位 chartInfo.ModifyTime = time.Now() updateCol = append(updateCol, "Sort", "ModifyTime") } //更新 if len(updateCol) > 0 { err = chartInfo.Update(updateCol) if err != nil { errMsg = "移动失败" err = errors.New("修改失败,Err:" + err.Error()) return } } } return } func GetChildChartClassifyByClassifyId(targetClassifyId int) (targetList []*data_manage.ChartClassifyIdItems, err error, errMsg string) { //判断是否是挂在顶级目录下 targetClassify, err := data_manage.GetChartClassifyById(targetClassifyId) if err != nil { if err.Error() == utils.ErrNoRow() { errMsg = "当前分类不存在" err = errors.New(errMsg) return } errMsg = "获取失败" err = errors.New("获取分类信息失败,Err:" + err.Error()) return } orderStr := ` order by level asc, sort asc, chart_classify_id asc` tmpList, err := data_manage.GetChartClassifyByRootIdLevel(targetClassify.RootId, targetClassify.Source, orderStr) if err != nil && err.Error() != utils.ErrNoRow() { errMsg = "获取失败" err = errors.New("获取数据失败,Err:" + err.Error()) return } idMap := make(map[int]struct{}) if len(tmpList) > 0 { for _, v := range tmpList { if v.ChartClassifyId == targetClassify.ChartClassifyId { idMap[v.ChartClassifyId] = struct{}{} } } for _, v := range tmpList { if _, ok := idMap[v.ParentId]; ok { idMap[v.ChartClassifyId] = struct{}{} } } for _, v := range tmpList { if _, ok := idMap[v.ChartClassifyId]; ok { targetItem := new(data_manage.ChartClassifyIdItems) targetItem.ChartClassifyId = v.ChartClassifyId targetItem.ParentId = v.ParentId targetItem.RootId = v.RootId targetItem.UniqueCode = v.UniqueCode targetItem.Level = v.Level targetItem.ChartClassifyName = v.ChartClassifyName targetItem.IsJoinPermission = v.IsJoinPermission targetList = append(targetList, targetItem) } } } return } func GetChartClassifyMaxSort(parentId, source int) (maxSort int, err error) { //获取该层级下最大的排序数 classifyMaxSort, err := data_manage.GetChartClassifyMaxSort(parentId, source) if err != nil { return } maxSort = classifyMaxSort edbMaxSort, err := data_manage.GetChartInfoMaxSortByClassifyId(parentId) if err != nil { return } if maxSort < edbMaxSort { maxSort = edbMaxSort } return } // GetChartClassifyTreeRecursive 递归获取分类树形结构 func GetChartClassifyTreeRecursive(list []*data_manage.ChartClassifyItems, parentId int) []*data_manage.ChartClassifyItems { res := make([]*data_manage.ChartClassifyItems, 0) for _, v := range list { if v.ParentId == parentId { v.Children = GetChartClassifyTreeRecursive(list, v.ChartClassifyId) res = append(res, v) } } return res } // GetChartClassifyParentRecursive 根据子目录递归父级目录 func GetChartClassifyParentRecursive(list []*data_manage.ChartClassifyItems, classifyId int) []*data_manage.ChartClassifyItems { res := make([]*data_manage.ChartClassifyItems, 0) for _, v := range list { if v.ChartClassifyId == classifyId { if v.ParentId > 0 { res = GetChartClassifyParentRecursive(list, v.ParentId) } res = append(res, v) } } return res } // 修改图表分类,可以修改父级 func EditChartClassifyV2(chartClassifyId, parentId, source int, chartClassifyName, lang string) (classifyInfo *data_manage.ChartClassify, err error, errMsg string, isSendEmail bool) { isSendEmail = true errMsg = "保存失败" // 获取分类信息 classifyInfo, err = data_manage.GetChartClassifyById(chartClassifyId) if err != nil { return } if parentId != classifyInfo.ParentId { parentClassifyInfo, e := data_manage.GetChartClassifyById(parentId) if e != nil { err = e return } if classifyInfo.Level != parentClassifyInfo.Level+1 { err = errors.New("父级分类层级异常") return } } // 分类来源校验 if classifyInfo.Source != source { errMsg = "图表分类异常" err = errors.New(fmt.Sprintf("图表分类来源异常,修改来源:%d,分类来源:%d", source, classifyInfo.Source)) isSendEmail = false return } // 需要变更的字段 updateCols := make([]string, 0) if parentId != classifyInfo.ParentId { classifyInfo.ParentId = parentId classifyInfo.ModifyTime = time.Now() updateCols = append(updateCols, "ParentId") } // 语言版本校验 switch lang { case utils.EnLangVersion: if classifyInfo.ChartClassifyNameEn != chartClassifyName { count, tmpErr := data_manage.GetChartClassifyEnCount(chartClassifyName, classifyInfo.ParentId, source) if tmpErr != nil { errMsg = "判断名称是否已存在失败" err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error()) return } if count > 0 { errMsg = "分类名称已存在,请重新输入" err = errors.New(errMsg) isSendEmail = false return } classifyInfo.ChartClassifyNameEn = chartClassifyName classifyInfo.ModifyTime = time.Now() updateCols = append(updateCols, "ChartClassifyNameEn", "ModifyTime") } default: if classifyInfo.ChartClassifyName != chartClassifyName { count, tmpErr := data_manage.GetChartClassifyCount(chartClassifyName, classifyInfo.ParentId, source) if tmpErr != nil { errMsg = "判断名称是否已存在失败" err = errors.New("判断名称是否已存在失败,Err:" + tmpErr.Error()) return } if count > 0 { errMsg = "分类名称已存在,请重新输入" err = errors.New(errMsg) isSendEmail = false return } classifyInfo.ChartClassifyName = chartClassifyName classifyInfo.ModifyTime = time.Now() updateCols = append(updateCols, "ChartClassifyName", "ModifyTime") } } if len(updateCols) > 0 { err = classifyInfo.Update(updateCols) } return } // RemoveNotChartClassifyItemsMakeTree // @Description: 过滤名下没有自己图表的分类,并生成树形结构 // @author: Roc // @datetime 2024-09-11 16:59:39 // @param node *data_manage.ChartClassifyItems // @param selfChartClassifyIdList []int // @return isSelf bool func RemoveNotChartClassifyItemsMakeTree(node *data_manage.ChartClassifyItems, selfChartClassifyIdList []int) (isSelf bool) { if utils.InArrayByInt(selfChartClassifyIdList, node.ChartClassifyId) { return true } childrenList := make([]*data_manage.ChartClassifyItems, 0) for _, child := range node.Children { if tmpIsSelf := RemoveNotChartClassifyItemsMakeTree(child, selfChartClassifyIdList); tmpIsSelf { childrenList = append(childrenList, child) isSelf = tmpIsSelf } } node.Children = childrenList return } // GetChartClassifyChildrenRecursive 根据父目录递归子级目录 func GetChartClassifyChildrenRecursive(list []*data_manage.ChartClassifyItems, parentId int) []*data_manage.ChartClassifyItems { var res []*data_manage.ChartClassifyItems for _, v := range list { if v.ParentId == parentId { // 递归调用以获取更深层次的子级 children := GetChartClassifyChildrenRecursive(list, v.ChartClassifyId) // 将当前节点和所有子节点添加到结果中 res = append(res, v) res = append(res, children...) } else if v.ChartClassifyId == parentId { // 将当前节点添加到结果中 res = append(res, v) } } return res } // GetChartClassifyChildrenRecursiveByParentIds 根据父目录递归子级目录 func GetChartClassifyChildrenRecursiveByParentIds(list []*data_manage.ChartClassifyItems, parentIds []string) []*data_manage.ChartClassifyItems { var res []*data_manage.ChartClassifyItems for _, v := range list { for _, id := range parentIds { parentId, _ := strconv.Atoi(id) if v.ParentId == parentId || v.ChartClassifyId == parentId { // 递归调用以获取更深层次的子级 children := GetChartClassifyChildrenRecursive(list, v.ChartClassifyId) // 将当前节点和所有子节点添加到结果中 res = append(res, v) res = append(res, children...) } } } return res } // GetChartClassifyRelation 获取图库分类的父级关系 map[classifyId]map[parentId]struct{} classifyId为图库classify_id, map[parentId]struct{}为当前分类id中所有的父级id func GetChartClassifyRelation() (classifyRelationMap map[int]map[int]struct{}, err error) { classifyAll, err := data_manage.GetChartClassifyBySource(utils.CHART_SOURCE_DEFAULT) if err != nil { return } classifyRelationMap = make(map[int]map[int]struct{}) for _, classify := range classifyAll { if classify.ParentId == 0 { classifyRelationMap[classify.ChartClassifyId] = make(map[int]struct{}) continue } if parent, ok := classifyRelationMap[classify.ParentId]; !ok { continue } else { if _, ok := classifyRelationMap[classify.ChartClassifyId]; !ok { classifyRelationMap[classify.ChartClassifyId] = make(map[int]struct{}) classifyRelationMap[classify.ChartClassifyId][classify.ParentId] = struct{}{} for k, v := range parent { classifyRelationMap[classify.ChartClassifyId][k] = v } } else { classifyRelationMap[classify.ChartClassifyId][classify.ParentId] = struct{}{} for k, v := range parent { classifyRelationMap[classify.ChartClassifyId][k] = v } } } } return } func GetChartClassifyByIsMe(adminId, parentId, source int, classifyList []*data_manage.ChartClassifyItems) (list []*data_manage.ChartClassifyItems, err error) { chartInfoList, err := data_manage.GetChartInfoByAdminId([]int{source}, adminId) if err != nil { return } classifyRelation, err := GetChartClassifyRelation() if err != nil { return } chartInfoRelationClassifyMap := make(map[int]struct{}) for _, classify := range chartInfoList { if classify.ChartClassifyId == 0 { continue } else { if relationClassify, ok := classifyRelation[classify.ChartClassifyId]; ok { chartInfoRelationClassifyMap[classify.ChartClassifyId] = struct{}{} for k, v := range relationClassify { chartInfoRelationClassifyMap[k] = v } } } } for _, classify := range classifyList { if classify.ChartInfoId > 0 { list = append(list, classify) } else { if _, ok := chartInfoRelationClassifyMap[classify.ChartClassifyId]; ok { list = append(list, classify) } } } return }