package service import ( "SSO/models" "fmt" "github.com/jinzhu/gorm" ) func getAllOriginPurviews(appType int) ([]*models.Purview, error) { var purviews []*models.Purview getPurviewErr := readUserDb.Model(models.Purview{}).Where("module = ? AND status = 1", appType).Order("listorder asc").Order("id asc").Find(&purviews).Error if getPurviewErr != nil { if getPurviewErr == gorm.ErrRecordNotFound { return nil, nil } else { return nil, getPurviewErr } } return purviews, nil } func GetAllPurviewsProcessed(appType int) ([]*models.Purview, error) { originPurviews, getPurviewErr := getAllOriginPurviews(appType) if getPurviewErr != nil { return nil, getPurviewErr } return processPurviews2Tree(originPurviews), nil } // 加工这些规则:树形化 // 正确结果的前提是 originPurviews 以 parentid asc 排好序了的 func processPurviews2Tree(originPurviews []*models.Purview) []*models.Purview { processedPurviews := make([]*models.Purview, 0) pid_childs := make(map[int][]*models.Purview) for _, purview := range originPurviews { // warning:下面这个算法只适用最多两层树形结构的菜单,对于两层以上的会丢失掉第三层及其以下的节点 // 因为取出 originPurviews 的时候已经排过序了,所以顶级节点肯定最先处理,不需要担心子节点比父节点先处理 if purview.Parentid == 0 { processedPurviews = append(processedPurviews, purview) } else { childs := pid_childs[purview.Parentid] if pid_childs[purview.Parentid] == nil { childs = make([]*models.Purview, 0) } childs = append(childs, purview) pid_childs[purview.Parentid] = childs } } for _, proPurview := range processedPurviews { proPurview.Childs = pid_childs[proPurview.Id] } return processedPurviews } func GetSuperAdminUsersPurviewTreeAndUrlfors(appType int) ([]string, []*models.Purview, error) { originPurviews, getPurviewErr := getAllOriginPurviews(appType) if getPurviewErr != nil { return nil, nil, getPurviewErr } urlfors, processedPurviews := getUrlforsAndProcessPurviews2Tree(originPurviews) return urlfors, processedPurviews, nil } func GetGeneralAdminUsersPurviewTreeAndUrlfors(adminUserID int, appId int) ([]string, []*models.Purview, error) { rows, err := readUserDb.Raw("SELECT p.purview_ids AS pids FROM sgj_user_admin_role AS a_r, sgj_user_role_purview AS p WHERE a_r.admin_user_id = ? AND a_r.app_id = ? AND a_r.role_id = p.role_id AND a_r.status = 1 AND p.`status` = 1;", adminUserID, appId).Rows() defer rows.Close() if err != nil { if err == gorm.ErrRecordNotFound { return make([]string, 0), make([]*models.Purview, 0), nil } else { return nil, nil, err } } pids := "" if rows.Next() { rows.Scan(&pids) } if len(pids) == 0 { return make([]string, 0), make([]*models.Purview, 0), nil } else { var originPurviews []*models.Purview getPurviewErr := readUserDb.Model(&models.Purview{}).Where(fmt.Sprintf("id in (%v) and status = 1", pids)).Order("listorder asc").Order("id asc").Find(&originPurviews).Error if getPurviewErr != nil { if err == gorm.ErrRecordNotFound { return make([]string, 0), make([]*models.Purview, 0), nil } else { return nil, nil, err } } else { urlfors, processedPurviews := getUrlforsAndProcessPurviews2Tree(originPurviews) return urlfors, processedPurviews, nil } } } // 加工这些规则:树形化;以及从中取出不为空的 urlfor // 正确结果的前提是 originPurviews 以 parentid asc 排好序了的 func getUrlforsAndProcessPurviews2Tree(originPurviews []*models.Purview) ([]string, []*models.Purview) { processedPurviews := make([]*models.Purview, 0) pid_childs := make(map[int][]*models.Purview) urlfors := make([]string, 0, len(originPurviews)) for _, purview := range originPurviews { if len(purview.Urlfor) != 0 { urlfors = append(urlfors, purview.Urlfor) } // warning:下面这个算法只适用最多两层树形结构的菜单,对于两层以上的会丢失掉第三层及其以下的节点 // 因为取出 originPurviews 的时候已经排过序了,所以顶级节点肯定最先处理,不需要担心子节点比父节点先处理 if purview.Parentid == 0 { processedPurviews = append(processedPurviews, purview) } else { childs := pid_childs[purview.Parentid] if pid_childs[purview.Parentid] == nil { childs = make([]*models.Purview, 0) } childs = append(childs, purview) pid_childs[purview.Parentid] = childs } } for _, proPurview := range processedPurviews { proPurview.Childs = pid_childs[proPurview.Id] } return urlfors, processedPurviews }