Browse Source

feat(新增行业图谱获取方法):算法逻辑调整,新增层次概念

Roc 4 years ago
parent
commit
ca8e6a885c
2 changed files with 184 additions and 121 deletions
  1. 27 1
      models/industry_map.go
  2. 157 120
      services/industry_map.go

+ 27 - 1
models/industry_map.go

@@ -30,6 +30,7 @@ type CygxIndustryMapItems struct {
 	IndustryMapId   int `orm:"column(industry_map_id);" description:"行业图谱id"`
 	IndustryMapName string
 	ParentId        int
+	Level        int
 	Children        []*CygxIndustryMapItems
 }
 
@@ -40,10 +41,35 @@ func GetCygxIndustryMapByParentId(parentId int) (items []*CygxIndustryMapItems,
 	return
 }
 
+func GetCygxIndustryMapByLevel(level int) (items []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE level=?`
+	_, err = o.Raw(sql, level).QueryRows(&items)
+	return
+}
+
 //根据名称模糊匹配获取一条数据
 func GetFirstCygxIndustryItemByName(industryName string) (items *CygxIndustryMapItems, err error) {
 	o := orm.NewOrm()
 	sql := ` SELECT * FROM cygx_industry_map WHERE industry_map_name like '%` + industryName + `%' order by industry_map_id asc`
 	err = o.Raw(sql).QueryRow(&items)
 	return
-}
+}
+
+//根据名称模糊匹配获取一条数据
+func GetFirstCygxIndustryListByName(industryName string) (list []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_industry_map WHERE industry_map_name like '%` + industryName + `%' order by level,industry_map_id asc`
+	_,err = o.Raw(sql).QueryRows(&list)
+	return
+}
+
+//根据名称模糊匹配获取一条数据
+func FixLevelData(industryMapId int,level int) (list []*CygxIndustryMapItems, err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_industry_map set level = ? WHERE industry_map_id = ?`
+	_,err = o.Raw(sql,level,industryMapId).QueryRows(&list)
+	return
+}
+
+//func

+ 157 - 120
services/industry_map.go

@@ -5,8 +5,10 @@ import (
 	"fmt"
 	"hongze/hongze_cygx/models"
 	"hongze/hongze_cygx/utils"
+	"math/rand"
+	"reflect"
 	"sort"
-	"strings"
+	"time"
 )
 
 
@@ -79,110 +81,85 @@ func GetIndustryTree()(rootNode *models.CygxIndustryMapItems, err error) {
 	return
 }
 
-//获取行业图谱切片
-func GetIndustryMapNameSlice(industryName string)(nameSlice []string,err error){
-	tree,err := GetIndustryTree()
-	if err != nil{
-		fmt.Println("获取树失败")
-		return
-	}
-	//fmt.Println(tree)
-
-	item,err := models.GetFirstCygxIndustryItemByName(industryName)
-	if err != nil{
-		fmt.Println("获取数据失败,",err)
-		return
-	}
-	var tmpSlice,tmpChildSlice,tmpParentSlice,tmpSiblingSlice,tmpSiblingChildSlice []*models.CygxIndustryMapItems
-
-	//已经存在的行业id的map集合
-	hasIdMap := make(map[int]string)
-	hasIdMap[item.IndustryMapId]=""
+//获取对应的层级map
+func getMap(tree *models.CygxIndustryMapItems,item *models.CygxIndustryMapItems,hasIdMap map[int]string,otherChildMapSlice map[int][]*models.CygxIndustryMapItems){
+	//深度
+	depth := 0
 
 	//获取下级
-	tmpChildSlice = childTreeToSlice(tree,item,tmpChildSlice,hasIdMap)
-	tmpSlice = append(tmpSlice,tmpChildSlice...)
-
+	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)
-	tmpSlice = append(tmpSlice,tmpParentSlice...)
-
-	//获取同级
-	tmpSiblingSlice = siblingTreeToSlice(tree,item,tmpSiblingSlice,hasIdMap)
-	tmpSlice = append(tmpSlice,tmpSiblingSlice...)
-
-
-	//获取同级的子级
-	for _,v := range tmpSiblingSlice{
-		tmpSiblingChildSlice = childTreeToSlice(v,v,tmpSiblingChildSlice,hasIdMap)
+	for _,v := range tmpParentSlice{
+		depth++
+		if _,ok := hasIdMap[v.IndustryMapId];ok==false{
+			otherChildMapSlice[depth] = append(otherChildMapSlice[depth],v)
+		}
 	}
-	tmpSlice = append(tmpSlice,tmpSiblingChildSlice...)
 
-	//名字切片
-	for _,v := range tmpSlice{
-		hasIdMap[v.IndustryMapId] = ""
-		nameSlice = append(nameSlice,v.IndustryMapName)
-	}
+	//获取同级
+	//fmt.Println("===============")
+	depth = siblingTreeToSlice(tree,item,hasIdMap,depth,otherChildMapSlice)
 
+	//上级的同级~
+	/*for _,parentSlice := range tmpParentSlice{
+		depth = siblingTreeToSlice(tree,parentSlice,hasIdMap,depth,otherChildMapSlice)
+	}*/
 	return
 }
 
-func TestGetStr(industryName string){
+//获取行业图谱切片
+func GetIndustryMapNameSlice(industryName string)(nameSlice []string,err error){
 	tree,err := GetIndustryTree()
 	if err != nil{
 		fmt.Println("获取树失败")
 	}
+
 	//fmt.Println(tree)
 
-	item,err := models.GetFirstCygxIndustryItemByName(industryName)
+	//已经存在的行业id的map集合
+	hasIdMap := make(map[int]string)
+	itemList,err := models.GetFirstCygxIndustryListByName(industryName)
 	if err != nil{
 		fmt.Println("获取数据失败,",err)
 	}
-	fmt.Println(item)
-	var tmpSlice,tmpChildSlice,tmpParentSlice,tmpSiblingSlice,tmpSiblingChildSlice []*models.CygxIndustryMapItems
-
-	//已经存在的行业id的map集合
-	hasIdMap := make(map[int]string)
-	hasIdMap[item.IndustryMapId]=""
-
-	//获取下级
-	tmpChildSlice = childTreeToSlice(tree,item,tmpChildSlice,hasIdMap)
-	tmpSlice = append(tmpSlice,tmpChildSlice...)
-	fmt.Println("下级获取结束")
-
-
-	//获取上级
-	tmpParentSlice,_ = parentTreeToSlice(tree,item,0,tmpParentSlice,hasIdMap)
-	//移除第一个最上级的行业
-	tmpParentSlice = append(tmpParentSlice[:0],tmpParentSlice[1:len(tmpParentSlice)]...)
-	tmpParentSlice = reverse(tmpParentSlice)
-	tmpSlice = append(tmpSlice,tmpParentSlice...)
-
-	//获取同级
-	tmpSiblingSlice = siblingTreeToSlice(tree,item,tmpSiblingSlice,hasIdMap)
-	tmpSlice = append(tmpSlice,tmpSiblingSlice...)
-
+	//找不到对应的数据
+	if len(itemList) <= 0{
+		return
+	}
+	//for k,item := range list{
+	//	fmt.Println(k)
+	//	fmt.Println(item)
+	//}
+	//return
+	industryMapList := make(map[int][]*models.CygxIndustryMapItems)
+	for _,item := range itemList{
+		industryMapList[item.Level] = append(industryMapList[item.Level],item)
+	}
 
-	//获取同级的子级
-	for _,v := range tmpSiblingSlice{
-		tmpSiblingChildSlice = childTreeToSlice(v,v,tmpSiblingChildSlice,hasIdMap)
+	//将查出来的根节点数据的key取出来,放在切片中,并对该切片做正序排列
+	var sortIndustryList []int
+	for k, _ := range industryMapList {
+		sortIndustryList = append(sortIndustryList, k)
 	}
-	tmpSlice = append(tmpSlice,tmpSiblingChildSlice...)
+	sort.Ints(sortIndustryList)
 
-	//获取其他的子级
-	//找到最上级
+	//最底层节点的数据集合
+	list := industryMapList[sortIndustryList[0]]
 
-	//遍历父级菜单,然后再去遍历对应的数据
-	depth := 0
 	otherChildMapSlice := map[int][]*models.CygxIndustryMapItems{}
-	for _,parentSlice := range tmpParentSlice{
-		depth++
-		childTreeToSliceTwo(parentSlice,hasIdMap,&depth,otherChildMapSlice)
+	for _,item := range list{
+		hasIdMap[item.IndustryMapId]=""
+		getMap(tree,item,hasIdMap,otherChildMapSlice)
 	}
+	var tmpSlice []*models.CygxIndustryMapItems
 
 	//将其他规律数据的key取出来,放在切片中,并对该切片做正序排列
 	var sortList []int
@@ -193,23 +170,24 @@ func TestGetStr(industryName string){
 
 	//遍历该切片,根据下标key获取对应的数据,并插入到主数据中
 	for _,v := range sortList{
-		tmpSlice = append(tmpSlice,otherChildMapSlice[v]...)
+		tmpChildSlice := otherChildMapSlice[v]
+		randSlice(tmpChildSlice)
+		tmpSlice = append(tmpSlice,tmpChildSlice...)
+		//fmt.Println(k,"=====")
+		//for _,tmpV := range otherChildMapSlice[v]{
+		//	fmt.Println(tmpV.IndustryMapName)
+		//}
 	}
-	//tmpSlice = append(tmpSlice,tmpOtherChildSlice...)
-	fmt.Println("获取其他子级结束")
-
 	//名字切片
-	var nameSlice []string
-	for k,v := range tmpSlice{
-		hasIdMap[v.IndustryMapId] = ""
-		fmt.Println("k===",k,"=======v=======",v)
+	for _,v := range tmpSlice{
+		//fmt.Println("k===",k,"=======v=======",v)
 		nameSlice = append(nameSlice,v.IndustryMapName)
 	}
-	fmt.Println("单次任务结束")
 
-	fmt.Println(nameSlice)
-	fmt.Println(strings.Join(nameSlice,","))
-	utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,","))
+	//fmt.Println(nameSlice)
+	//fmt.Println(strings.Join(nameSlice,","))
+	//utils.FileLog.Info("allNodes:%s",strings.Join(nameSlice,","))
+	return
 }
 
 //切片反转
@@ -220,21 +198,21 @@ func reverse(s []*models.CygxIndustryMapItems) []*models.CygxIndustryMapItems {
 	return s
 }
 
-//查找某个节点的下级树
-func childTreeToSlice(rootNode *models.CygxIndustryMapItems,nowNode *models.CygxIndustryMapItems,tmpSlice []*models.CygxIndustryMapItems,hasIdMap map[int]string) (returnSlice []*models.CygxIndustryMapItems)  {
-	returnSlice = tmpSlice
-	//var parentSlice []string
+//获取当前节点的树
+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.ParentId == nowNode.IndustryMapId{
-				if _,ok := hasIdMap[v.IndustryMapId];ok==false{
-					returnSlice = append(returnSlice,v)
-					hasIdMap[v.IndustryMapId] = ""
-				}
-				returnSlice = childTreeToSlice(v,v,returnSlice,hasIdMap)
-
-			}else {
-				returnSlice = childTreeToSlice(v,nowNode,returnSlice,hasIdMap)
+			if v.IndustryMapId == nowNode.IndustryMapId{
+				returnNode = v
+			}else{
+				returnNode = getChildTree(v,nowNode)
+			}
+			if returnNode != nil{
+				return
 			}
 		}
 	}
@@ -242,13 +220,14 @@ func childTreeToSlice(rootNode *models.CygxIndustryMapItems,nowNode *models.Cygx
 }
 
 //获取子树V2,与上一个子树规律不一样,因为上级
-func childTreeToSliceTwo(rootNode *models.CygxIndustryMapItems,hasIdMap map[int]string,depth *int,otherChildMapSlice map[int][]*models.CygxIndustryMapItems) {
-	*depth++
+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)
+				otherChildMapSlice[depth] = append(otherChildMapSlice[depth],v)
 			}
 		}
 
@@ -256,30 +235,46 @@ func childTreeToSliceTwo(rootNode *models.CygxIndustryMapItems,hasIdMap map[int]
 			//判断是否已经录入,如果已经录入,那么不处理
 			if _,ok := hasIdMap[v.IndustryMapId];ok==false{
 				hasIdMap[v.IndustryMapId] = ""
-				childTreeToSliceTwo(v,hasIdMap,depth,otherChildMapSlice)
+				returnDepth := childTreeToSlice(v,hasIdMap,depth,otherChildMapSlice)
+				if returnDepth > maxDepth{
+					maxDepth = returnDepth
+				}
 			}
 		}
 	}
-	return
+	return maxDepth
 }
 
 //获取兄弟级树
-func siblingTreeToSlice(rootNode *models.CygxIndustryMapItems,nowNode *models.CygxIndustryMapItems,tmpReturnSlice []*models.CygxIndustryMapItems,hasIdMap map[int]string) (returnSlice []*models.CygxIndustryMapItems)  {
-	//var parentSlice []string
-	returnSlice = tmpReturnSlice
+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 v.IndustryMapId != nowNode.IndustryMapId{
-					if _,ok := hasIdMap[v.IndustryMapId];ok==false{
-						returnSlice = append(returnSlice,v)
-						hasIdMap[v.IndustryMapId] = ""
+				//判断是否已经录入,如果已经录入,那么不处理
+				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{
-				returnSlice = siblingTreeToSlice(v,nowNode,returnSlice,hasIdMap)
+				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] = ""
+				}
+
 			}
 		}
 	}
@@ -292,10 +287,10 @@ func parentTreeToSlice(rootNode *models.CygxIndustryMapItems,nowNode *models.Cyg
 		returnSlice = tmpReturnSlice
 	}
 	depth++
-	if _,ok := hasIdMap[rootNode.IndustryMapId];ok==false{
-		returnSlice = append(returnSlice,rootNode)
-		hasIdMap[rootNode.IndustryMapId] = ""
-	}
+	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{
@@ -316,3 +311,45 @@ func parentTreeToSlice(rootNode *models.CygxIndustryMapItems,nowNode *models.Cyg
 	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
+}
+//region数据修复
+func FixData(){
+	tree,err := GetIndustryTree()
+	if err != nil{
+		fmt.Println("获取树失败")
+	}
+	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