package services import ( "fmt" "hongze/hongze_clpt/models" "math/rand" "reflect" "sort" "time" ) func MakeTree(allNode []*models.CygxIndustryMapItems, node *models.CygxIndustryMapItems) { childs, _ := haveChild(allNode, node) //判断节点是否有子节点并返回 if len(childs) > 0 { node.Children = append(node.Children, childs[0:]...) //添加子节点 for _, v := range childs { //查询子节点的子节点,并添加到子节点 _, has := haveChild(allNode, v) if has { MakeTree(allNode, v) //递归添加节点 } } } } func haveChild(allNode []*models.CygxIndustryMapItems, node *models.CygxIndustryMapItems) (childs []*models.CygxIndustryMapItems, yes bool) { for _, v := range allNode { if v.ParentId == node.IndustryMapId { childs = append(childs, v) } } if len(childs) > 0 { yes = true } return } func GetIndustryMap() { list, err := models.GetCygxIndustryMapByParentId(0) if err != nil { return } rootNode := list[0] allNodes, err := models.GetCygxIndustryMapAll() if err != nil { return } MakeTree(allNodes, rootNode) } func GetIndustryTree() (rootNode *models.CygxIndustryMapItems, err error) { //fmt.Println("start") list, err := models.GetCygxIndustryMapByParentId(0) if err != nil { return } rootNode = list[0] allNodes, err := models.GetCygxIndustryMapAll() if err != nil { return } MakeTree(allNodes, rootNode) //resultJson,err:=json.Marshal(rootNode) //fmt.Println("Err:",err) //fmt.Println("allNodes:",string(resultJson)) //utils.FileLog.Info("allNodes:%s",string(resultJson)) //fmt.Println("end") return } //获取对应的层级map func getMap(tree *models.CygxIndustryMapItems, item *models.CygxIndustryMapItems, hasIdMap map[int]string, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) { //深度 depth := 1 //获取下级 childTree := getChildTree(tree, item) depth = childTreeToSlice(childTree, hasIdMap, depth, otherChildMapSlice) //获取上级 var tmpParentSlice []*models.CygxIndustryMapItems tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap) //移除第一个最上级的行业(根节点) tmpParentSlice = append(tmpParentSlice[:0], tmpParentSlice[1:len(tmpParentSlice)]...) //切片反转 tmpParentSlice = reverse(tmpParentSlice) for _, v := range tmpParentSlice { depth++ if _, ok := hasIdMap[v.IndustryMapId]; ok == false { otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v) } } //获取同级 //fmt.Println("===============") depth = siblingTreeToSlice(tree, item, hasIdMap, depth, otherChildMapSlice) //上级的同级~ /*for _,parentSlice := range tmpParentSlice{ depth = siblingTreeToSlice(tree,parentSlice,hasIdMap,depth,otherChildMapSlice) }*/ return } //获取行业图谱切片 func GetIndustryMapNameSlice(industryName string) (nameSlice []string, err error) { nameSlice = append(nameSlice, industryName) tree, err := GetIndustryTree() if err != nil { return } //已经存在的行业id的map集合 hasIdMap := make(map[int]string) itemList, err := models.GetFirstCygxIndustryListByName(industryName) if err != nil { return } //找不到对应的数据 if len(itemList) <= 0 { return } industryMapList := make(map[int][]*models.CygxIndustryMapItems) for _, item := range itemList { industryMapList[item.Level] = append(industryMapList[item.Level], item) } //将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列 var sortIndustryList []int for k, _ := range industryMapList { sortIndustryList = append(sortIndustryList, k) } sort.Ints(sortIndustryList) //最底层节点的数据集合 list := industryMapList[sortIndustryList[0]] otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{} for _, item := range list { hasIdMap[item.IndustryMapId] = "" //将自己的节点给加进去 otherChildMapSlice[0] = append(otherChildMapSlice[0], item) getMap(tree, item, hasIdMap, otherChildMapSlice) } var tmpSlice []*models.CygxIndustryMapItems //将其他规律数据的key取出来,放在切片中,并对该切片做正序排列 var sortList []int for k, _ := range otherChildMapSlice { sortList = append(sortList, k) } sort.Ints(sortList) //遍历该切片,根据下标key获取对应的数据,并插入到主数据中 for _, v := range sortList { tmpChildSlice := otherChildMapSlice[v] randSlice(tmpChildSlice) tmpSlice = append(tmpSlice, tmpChildSlice...) //fmt.Println(k,"=====") //for _,tmpV := range otherChildMapSlice[v]{ // fmt.Println(tmpV.IndustryMapName) //} } //名字切片 for _, v := range tmpSlice { //fmt.Println("k===",k,"=======v=======",v) nameSlice = append(nameSlice, v.IndustryMapName) } //fmt.Println(nameSlice) //fmt.Println(strings.Join(nameSlice,",")) //utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,",")) return } //切片反转 func reverse(s []*models.CygxIndustryMapItems) []*models.CygxIndustryMapItems { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } return s } //获取当前节点的树 func getChildTree(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems) (returnNode *models.CygxIndustryMapItems) { if rootNode.IndustryMapId == nowNode.IndustryMapId { returnNode = rootNode return } if rootNode.Children != nil { for _, v := range rootNode.Children { if v.IndustryMapId == nowNode.IndustryMapId { returnNode = v } else { returnNode = getChildTree(v, nowNode) } if returnNode != nil { return } } } return } //获取子树V2,与上一个子树规律不一样,因为上级 func childTreeToSlice(rootNode *models.CygxIndustryMapItems, hasIdMap map[int]string, depth int, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) (maxDepth int) { if rootNode.Children != nil { depth++ maxDepth = depth for _, v := range rootNode.Children { //判断是否已经录入,如果已经录入,那么不处理 if _, ok := hasIdMap[v.IndustryMapId]; ok == false { otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v) } } for _, v := range rootNode.Children { //判断是否已经录入,如果已经录入,那么不处理 if _, ok := hasIdMap[v.IndustryMapId]; ok == false { hasIdMap[v.IndustryMapId] = "" returnDepth := childTreeToSlice(v, hasIdMap, depth, otherChildMapSlice) if returnDepth > maxDepth { maxDepth = returnDepth } } } } return maxDepth } //获取兄弟级树 func siblingTreeToSlice(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems, hasIdMap map[int]string, depth int, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) (maxDepth int) { if rootNode.Children != nil { depth++ maxDepth = depth for _, v := range rootNode.Children { //如果父级id一致的情况下,那么代表这是兄弟节点或者是自己了 if v.ParentId == nowNode.ParentId { //判断是否已经录入,如果已经录入,那么不处理 if _, ok := hasIdMap[v.IndustryMapId]; ok == false { otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v) returnDepth := childTreeToSlice(v, hasIdMap, depth, otherChildMapSlice) if returnDepth > maxDepth { maxDepth = returnDepth } } } else { returnDepth := siblingTreeToSlice(v, nowNode, hasIdMap, depth, otherChildMapSlice) if returnDepth > maxDepth { maxDepth = returnDepth } } } for _, v := range rootNode.Children { if v.ParentId == nowNode.ParentId { if _, ok := hasIdMap[v.IndustryMapId]; ok == false { hasIdMap[v.IndustryMapId] = "" } } } } return } //获取上级树 func parentTreeToSlice(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems, depth int, tmpReturnSlice []*models.CygxIndustryMapItems, hasIdMap map[int]string) (returnSlice []*models.CygxIndustryMapItems, ok bool) { if depth != 0 { returnSlice = tmpReturnSlice } depth++ returnSlice = append(returnSlice, rootNode) //if _,ok := hasIdMap[rootNode.IndustryMapId];ok==false{ // hasIdMap[rootNode.IndustryMapId] = "" //} if rootNode.Children != nil { for _, v := range rootNode.Children { if v.ParentId == nowNode.ParentId { ok = true return } returnSlice, ok = parentTreeToSlice(v, nowNode, depth, returnSlice, hasIdMap) //如果返回的匹配完成,那么不进入下一次循环,直接返回 if ok { return } //一次循环结束后,如果没有匹配上,那么移除临时切片中的数据 returnSlice = append(returnSlice[:0], returnSlice[0:depth]...) } } return } //切片乱序 func randSlice(slice []*models.CygxIndustryMapItems) { rv := reflect.ValueOf(slice) if rv.Type().Kind() != reflect.Slice { return } length := rv.Len() if length < 2 { return } swap := reflect.Swapper(slice) rand.Seed(time.Now().Unix()) for i := length - 1; i >= 0; i-- { j := rand.Intn(length) swap(i, j) } return } //获取行业图谱切片(v2版本,调整时间:2021-03-19 18:02:07) func GetIndustryMapNameSliceV2(industryName string) (nameSlice []string, err error) { nameSlice = append(nameSlice, industryName) tree, err := GetIndustryTree() if err != nil { fmt.Println("获取树失败") return } //fmt.Println(tree) //已经存在的行业id的map集合 hasIdMap := make(map[int]string) itemList, err := models.GetFirstCygxIndustryListByName(industryName) if err != nil { fmt.Println("获取数据失败,", err) return } //找不到对应的数据 if len(itemList) <= 0 { return } industryMapList := make(map[int][]*models.CygxIndustryMapItems) //TODO 这里好像有问题,如果传入行业的话,上面再没有是否只是找到第一个节点判断,那么就会异常抛出 for _, item := range itemList { industryMapList[item.Level] = append(industryMapList[item.Level], item) } //将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列 var sortIndustryList []int for k, _ := range industryMapList { sortIndustryList = append(sortIndustryList, k) } sort.Ints(sortIndustryList) //最底层节点的数据集合 list := industryMapList[sortIndustryList[0]] //如果该数据正好是第一层节点数据,那么需要额外判断下 if list[0].ParentId <= 2 { //如果存在第二级,那么就使用该层级 if len(sortIndustryList) > 1 { list = industryMapList[sortIndustryList[1]] } } //fmt.Println(list) //return otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{} //多个节点时,额外处理 if len(list) > 1 { for _, item := range list { hasIdMap[item.IndustryMapId] = "" //将自己的节点给加进去 otherChildMapSlice[0] = append(otherChildMapSlice[0], item) //获取上级 var tmpParentSlice []*models.CygxIndustryMapItems tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap) //父节点 parentItem := tmpParentSlice[len(tmpParentSlice)-1] if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false { hasIdMap[parentItem.IndustryMapId] = "" otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem) } } } else { //匹配到单个节点 item := list[0] hasIdMap[item.IndustryMapId] = "" //将自己的节点给加进去 otherChildMapSlice[0] = append(otherChildMapSlice[0], item) childTree := getChildTree(tree, item) //如果是命中到最后一层节点 if len(childTree.Children) == 0 { //获取上级 var tmpParentSlice []*models.CygxIndustryMapItems tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap) //父节点 parentItem := tmpParentSlice[len(tmpParentSlice)-1] if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false { hasIdMap[parentItem.IndustryMapId] = "" otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem) } //兄弟节点 siblingTreeToSliceV2(parentItem, item, hasIdMap, 2, otherChildMapSlice) } else { //如果不是命中到最后一层节点 otherChildMapSlice[1] = append(otherChildMapSlice[1], childTree.Children...) } } //return var tmpSlice []*models.CygxIndustryMapItems //将其他规律数据的key取出来,放在切片中,并对该切片做正序排列 var sortList []int for k, _ := range otherChildMapSlice { sortList = append(sortList, k) } sort.Ints(sortList) //遍历该切片,根据下标key获取对应的数据,并插入到主数据中 for _, v := range sortList { tmpChildSlice := otherChildMapSlice[v] randSlice(tmpChildSlice) tmpSlice = append(tmpSlice, tmpChildSlice...) //fmt.Println(k,"=====") //for _,tmpV := range otherChildMapSlice[v]{ // fmt.Println(tmpV.IndustryMapName) //} } //名字切片 for _, v := range tmpSlice { //fmt.Println("k===",k,"=======v=======",v) nameSlice = append(nameSlice, v.IndustryMapName) } //fmt.Println(nameSlice) //fmt.Println(strings.Join(nameSlice,",")) //utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,",")) return } //获取行业图谱切片(v3版本,调整时间:2021-04-20 17:23:31,不乱序) func GetIndustryMapNameSliceV3(industryName string) (nameSlice []string, err error) { nameSlice = append(nameSlice, industryName) tree, err := GetIndustryTree() if err != nil { fmt.Println("获取树失败") return } //fmt.Println(tree) //已经存在的行业id的map集合 hasIdMap := make(map[int]string) itemList, err := models.GetFirstCygxIndustryListByName(industryName) if err != nil { fmt.Println("获取数据失败,", err) return } //找不到对应的数据 if len(itemList) <= 0 { return } industryMapList := make(map[int][]*models.CygxIndustryMapItems) //TODO 这里好像有问题,如果传入行业的话,上面再没有是否只是找到第一个节点判断,那么就会异常抛出 for _, item := range itemList { industryMapList[item.Level] = append(industryMapList[item.Level], item) } //将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列 var sortIndustryList []int for k, _ := range industryMapList { sortIndustryList = append(sortIndustryList, k) } sort.Ints(sortIndustryList) //最底层节点的数据集合 list := industryMapList[sortIndustryList[0]] //如果该数据正好是第一层节点数据,那么需要额外判断下 if list[0].ParentId <= 2 { //如果存在第二级,那么就使用该层级 if len(sortIndustryList) > 1 { list = industryMapList[sortIndustryList[1]] } } //fmt.Println(list) //return otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{} //多个节点时,额外处理 if len(list) > 1 { for _, item := range list { hasIdMap[item.IndustryMapId] = "" //将自己的节点给加进去 otherChildMapSlice[0] = append(otherChildMapSlice[0], item) //获取上级 var tmpParentSlice []*models.CygxIndustryMapItems tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap) //父节点 parentItem := tmpParentSlice[len(tmpParentSlice)-1] if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false { hasIdMap[parentItem.IndustryMapId] = "" otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem) } } } else { //匹配到单个节点 item := list[0] hasIdMap[item.IndustryMapId] = "" //将自己的节点给加进去 otherChildMapSlice[0] = append(otherChildMapSlice[0], item) childTree := getChildTree(tree, item) //如果是命中到最后一层节点 if len(childTree.Children) == 0 { //获取上级 var tmpParentSlice []*models.CygxIndustryMapItems tmpParentSlice, _ = parentTreeToSlice(tree, item, 0, tmpParentSlice, hasIdMap) //父节点 parentItem := tmpParentSlice[len(tmpParentSlice)-1] if _, ok := hasIdMap[parentItem.IndustryMapId]; ok == false { hasIdMap[parentItem.IndustryMapId] = "" otherChildMapSlice[1] = append(otherChildMapSlice[1], parentItem) } //兄弟节点 siblingTreeToSliceV2(parentItem, item, hasIdMap, 2, otherChildMapSlice) } else { //如果不是命中到最后一层节点 otherChildMapSlice[1] = append(otherChildMapSlice[1], childTree.Children...) } } //return var tmpSlice []*models.CygxIndustryMapItems //将其他规律数据的key取出来,放在切片中,并对该切片做正序排列 var sortList []int for k, _ := range otherChildMapSlice { sortList = append(sortList, k) } sort.Ints(sortList) //遍历该切片,根据下标key获取对应的数据,并插入到主数据中 for _, v := range sortList { tmpChildSlice := otherChildMapSlice[v] //randSlice(tmpChildSlice) tmpSlice = append(tmpSlice, tmpChildSlice...) //fmt.Println(k,"=====") //for _,tmpV := range otherChildMapSlice[v]{ // fmt.Println(tmpV.IndustryMapName) //} } //名字切片 for _, v := range tmpSlice { //fmt.Println("k===",k,"=======v=======",v) nameSlice = append(nameSlice, v.IndustryMapName) } //fmt.Println(nameSlice) //fmt.Println(strings.Join(nameSlice,",")) //utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,",")) return } //获取兄弟级树 func siblingTreeToSliceV2(rootNode *models.CygxIndustryMapItems, nowNode *models.CygxIndustryMapItems, hasIdMap map[int]string, depth int, otherChildMapSlice map[int][]*models.CygxIndustryMapItems) (maxDepth int) { if rootNode.Children != nil { depth++ maxDepth = depth for _, v := range rootNode.Children { //如果父级id一致的情况下,那么代表这是兄弟节点或者是自己了 if v.ParentId == nowNode.ParentId { //判断是否已经录入,如果已经录入,那么不处理 if _, ok := hasIdMap[v.IndustryMapId]; ok == false { otherChildMapSlice[depth] = append(otherChildMapSlice[depth], v) hasIdMap[v.IndustryMapId] = "" } } else { returnDepth := siblingTreeToSliceV2(v, nowNode, hasIdMap, depth, otherChildMapSlice) if returnDepth > maxDepth { maxDepth = returnDepth } } } } return } //region数据修复 func FixData() { tree, err := GetIndustryTree() if err != nil { } models.FixLevelData(tree.IndustryMapId, 1) fixData(tree, 1) return } func fixData(item *models.CygxIndustryMapItems, depth int) { depth++ if item.Children == nil { return } for _, v := range item.Children { models.FixLevelData(v.IndustryMapId, depth) fixData(v, depth) } } //endregion