package models import ( "github.com/astaxie/beego/orm" "bytes" "strconv" "github.com/astaxie/beego" "html/template" ) type DocumentTree struct { DocumentId int `json:"id"` DocumentName string `json:"text"` ParentId interface{} `json:"parent"` Identify string `json:"identify"` BookIdentify string `json:"-"` Version int64 `json:"version"` State *DocumentSelected `json:"state,omitempty"` } type DocumentSelected struct { Selected bool `json:"selected"` Opened bool `json:"opened"` } //获取项目的文档树状结构 func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){ o := orm.NewOrm() trees := make([]*DocumentTree,0) var docs []*Document count ,err := o.QueryTable(m).Filter("book_id",book_id).OrderBy("order_sort","document_id").All(&docs,"document_id","version","document_name","parent_id","identify") if err != nil { return trees,err } book,_ := NewBook().Find(book_id) trees = make([]*DocumentTree,count) for index,item := range docs { tree := &DocumentTree{} if index == 0{ tree.State = &DocumentSelected{ Selected: true, Opened: true } } tree.DocumentId = item.DocumentId tree.Identify = item.Identify tree.Version = item.Version tree.BookIdentify = book.Identify if item.ParentId > 0 { tree.ParentId = item.ParentId }else{ tree.ParentId = "#" } tree.DocumentName = item.DocumentName trees[index] = tree } return trees,nil } func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string,error) { trees,err := m.FindDocumentTree(book_id) if err != nil { return "",err } parent_id := getSelectedNode(trees,selected_id) buf := bytes.NewBufferString("") getDocumentTree(trees,0,selected_id,parent_id,buf) return buf.String(),nil } //使用递归的方式获取指定ID的顶级ID func getSelectedNode(array []*DocumentTree, parent_id int) int { for _,item := range array { if _,ok := item.ParentId.(string); ok && item.DocumentId == parent_id { return item.DocumentId }else if pid,ok := item.ParentId.(int); ok && item.DocumentId == parent_id{ return getSelectedNode(array,pid) } } return 0 } func getDocumentTree(array []*DocumentTree,parent_id int,selected_id int,selected_parent_id int,buf *bytes.Buffer) { buf.WriteString("<ul>") for _,item := range array { pid := 0 if p, ok := item.ParentId.(int); ok { pid = p } if pid == parent_id { selected := "" if item.DocumentId == selected_id { selected = ` class="jstree-clicked"` } selected_li := "" if item.DocumentId == selected_parent_id { selected_li = ` class="jstree-open"` } buf.WriteString("<li id=\"") buf.WriteString(strconv.Itoa(item.DocumentId)) buf.WriteString("\"") buf.WriteString(selected_li) buf.WriteString("><a href=\"") if item.Identify != "" { uri := beego.URLFor("DocumentController.Read", ":key", item.BookIdentify, ":id", item.Identify) buf.WriteString(uri) } else { uri := beego.URLFor("DocumentController.Read", ":key", item.BookIdentify, ":id", item.DocumentId) buf.WriteString(uri) } buf.WriteString("\" title=\"") buf.WriteString(template.HTMLEscapeString(item.DocumentName) + "\"") buf.WriteString(selected + ">") buf.WriteString(template.HTMLEscapeString(item.DocumentName) + "</a>") for _, sub := range array { if p, ok := sub.ParentId.(int); ok && p == item.DocumentId { getDocumentTree(array, p, selected_id, selected_parent_id, buf) break } } buf.WriteString("</li>") } } buf.WriteString("</ul>") }