1、优化文档缓存逻辑

2、新增标签管理功能
3、优化部分页面显示效果
This commit is contained in:
Minho
2018-02-28 15:47:00 +08:00
parent 849058ff8a
commit b93052cc09
25 changed files with 365 additions and 111 deletions

View File

@@ -123,7 +123,15 @@ func (c *BaseController) BaseUrl() string {
//显示错误信息页面. //显示错误信息页面.
func (c *BaseController) ShowErrorPage(errCode int, errMsg string) { func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
c.TplName = "errors/error.tpl" c.TplName = "errors/error.tpl"
c.Data["ErrorMessage"] = errMsg c.Data["ErrorMessage"] = errMsg
c.Data["ErrorCode"] = errCode c.Data["ErrorCode"] = errCode
c.StopRun()
var buf bytes.Buffer
if err := beego.ExecuteViewPathTemplate(&buf, "document/export.tpl", beego.BConfig.WebConfig.ViewsPath, map[string]interface{}{"ErrorMessage": errMsg, "errCode": errCode, "BaseUrl": conf.BaseUrl}); err != nil {
c.Abort("500")
}
c.CustomAbort(200,buf.String())
} }

View File

@@ -42,6 +42,10 @@ func (c *BookController) Index() {
c.Abort("500") c.Abort("500")
} }
for i,book := range books {
books[i].Description = utils.StripTags(string(blackfriday.MarkdownBasic([]byte(book.Description))))
}
if totalCount > 0 { if totalCount > 0 {
pager := pagination.NewPagination(c.Ctx.Request,totalCount,conf.PageSize) pager := pagination.NewPagination(c.Ctx.Request,totalCount,conf.PageSize)
c.Data["PageHtml"] = pager.HtmlPages() c.Data["PageHtml"] = pager.HtmlPages()
@@ -135,6 +139,7 @@ func (c *BookController) SaveBook() {
autoRelease := strings.TrimSpace(c.GetString("auto_release")) == "on" autoRelease := strings.TrimSpace(c.GetString("auto_release")) == "on"
publisher := strings.TrimSpace(c.GetString("publisher")) publisher := strings.TrimSpace(c.GetString("publisher"))
historyCount,_ := c.GetInt("history_count",0) historyCount,_ := c.GetInt("history_count",0)
isDownload := strings.TrimSpace(c.GetString("is_download")) == "on"
if strings.Count(description, "") > 500 { if strings.Count(description, "") > 500 {
c.JsonResult(6004, "项目描述不能大于500字") c.JsonResult(6004, "项目描述不能大于500字")
@@ -159,13 +164,18 @@ func (c *BookController) SaveBook() {
book.Label = tag book.Label = tag
book.Editor = editor book.Editor = editor
book.HistoryCount = historyCount book.HistoryCount = historyCount
book.IsDownload = 0
if autoRelease { if autoRelease {
book.AutoRelease = 1 book.AutoRelease = 1
} else { } else {
book.AutoRelease = 0 book.AutoRelease = 0
} }
if isDownload {
book.IsDownload = 0
}else{
book.IsDownload = 1
}
if err := book.Update(); err != nil { if err := book.Update(); err != nil {
c.JsonResult(6006, "保存失败") c.JsonResult(6006, "保存失败")
} }
@@ -395,7 +405,7 @@ func (c *BookController) Create() {
book_name := strings.TrimSpace(c.GetString("book_name", "")) book_name := strings.TrimSpace(c.GetString("book_name", ""))
identify := strings.TrimSpace(c.GetString("identify", "")) identify := strings.TrimSpace(c.GetString("identify", ""))
description := strings.TrimSpace(c.GetString("description", "")) description := strings.TrimSpace(c.GetString("description", ""))
privately_owned, _ := strconv.Atoi(c.GetString("privately_owned")) privatelyOwned, _ := strconv.Atoi(c.GetString("privately_owned"))
comment_status := c.GetString("comment_status") comment_status := c.GetString("comment_status")
if book_name == "" { if book_name == "" {
@@ -413,8 +423,8 @@ func (c *BookController) Create() {
if strings.Count(description, "") > 500 { if strings.Count(description, "") > 500 {
c.JsonResult(6004, "项目描述不能大于500字") c.JsonResult(6004, "项目描述不能大于500字")
} }
if privately_owned != 0 && privately_owned != 1 { if privatelyOwned != 0 && privatelyOwned != 1 {
privately_owned = 1 privatelyOwned = 1
} }
if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" { if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" {
comment_status = "closed" comment_status = "closed"
@@ -460,7 +470,7 @@ func (c *BookController) Create() {
book.BookName = book_name book.BookName = book_name
book.Description = description book.Description = description
book.CommentCount = 0 book.CommentCount = 0
book.PrivatelyOwned = privately_owned book.PrivatelyOwned = privatelyOwned
book.CommentStatus = comment_status book.CommentStatus = comment_status
book.Identify = identify book.Identify = identify
book.DocCount = 0 book.DocCount = 0
@@ -487,7 +497,7 @@ func (c *BookController) Create() {
} }
c.JsonResult(6001, "error") c.JsonResult(6001, "error")
} }
//导入
func (c *BookController) Import() { func (c *BookController) Import() {
file, moreFile, err := c.GetFile("import-file") file, moreFile, err := c.GetFile("import-file")

View File

@@ -169,13 +169,13 @@ func (c *DocumentController) Read() {
doc := models.NewDocument() doc := models.NewDocument()
if doc_id, err := strconv.Atoi(id); err == nil { if doc_id, err := strconv.Atoi(id); err == nil {
doc, err = doc.Find(doc_id) doc, err = doc.FromCacheById(doc_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.Abort("500") c.Abort("500")
} }
} else { } else {
doc, err = doc.FindByFieldFirst("identify", id) doc, err = doc.FromCacheByIdentify(id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
c.Abort("500") c.Abort("500")
@@ -723,14 +723,14 @@ func (c *DocumentController) Content() {
c.Prepare() c.Prepare()
identify := c.Ctx.Input.Param(":key") identify := c.Ctx.Input.Param(":key")
doc_id, err := c.GetInt("doc_id") docId, err := c.GetInt("doc_id")
if err != nil { if err != nil {
doc_id, _ = strconv.Atoi(c.Ctx.Input.Param(":id")) docId, _ = strconv.Atoi(c.Ctx.Input.Param(":id"))
} }
book_id := 0 bookId := 0
auto_release := false autoRelease := false
// 如果是超级管理员,则忽略权限 // 如果是超级管理员,则忽略权限
if c.Member.IsAdministrator() { if c.Member.IsAdministrator() {
@@ -739,8 +739,8 @@ func (c *DocumentController) Content() {
c.JsonResult(6002, "项目不存在或权限不足") c.JsonResult(6002, "项目不存在或权限不足")
} }
book_id = book.BookId bookId = book.BookId
auto_release = book.AutoRelease == 1 autoRelease = book.AutoRelease == 1
} else { } else {
bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId) bookResult, err := models.NewBookResult().FindByIdentify(identify, c.Member.MemberId)
@@ -749,11 +749,11 @@ func (c *DocumentController) Content() {
c.JsonResult(6002, "项目不存在或权限不足") c.JsonResult(6002, "项目不存在或权限不足")
} }
book_id = bookResult.BookId bookId = bookResult.BookId
auto_release = bookResult.AutoRelease autoRelease = bookResult.AutoRelease
} }
if doc_id <= 0 { if docId <= 0 {
c.JsonResult(6001, "参数错误") c.JsonResult(6001, "参数错误")
} }
@@ -761,25 +761,25 @@ func (c *DocumentController) Content() {
markdown := strings.TrimSpace(c.GetString("markdown", "")) markdown := strings.TrimSpace(c.GetString("markdown", ""))
content := c.GetString("html") content := c.GetString("html")
version, _ := c.GetInt64("version", 0) version, _ := c.GetInt64("version", 0)
is_cover := c.GetString("cover") isCover := c.GetString("cover")
doc, err := models.NewDocument().Find(doc_id) doc, err := models.NewDocument().Find(docId)
if err != nil { if err != nil {
c.JsonResult(6003, "读取文档错误") c.JsonResult(6003, "读取文档错误")
} }
if doc.BookId != book_id { if doc.BookId != bookId {
c.JsonResult(6004, "保存的文档不属于指定项目") c.JsonResult(6004, "保存的文档不属于指定项目")
} }
if doc.Version != version && !strings.EqualFold(is_cover, "yes") { if doc.Version != version && !strings.EqualFold(isCover, "yes") {
beego.Info("%d|", version, doc.Version) beego.Info("%d|", version, doc.Version)
c.JsonResult(6005, "文档已被修改确定要覆盖吗?") c.JsonResult(6005, "文档已被修改确定要覆盖吗?")
} }
history := models.NewDocumentHistory() history := models.NewDocumentHistory()
history.DocumentId = doc_id history.DocumentId = docId
history.Content = doc.Content history.Content = doc.Content
history.Markdown = doc.Markdown history.Markdown = doc.Markdown
history.DocumentName = doc.DocumentName history.DocumentName = doc.DocumentName
@@ -812,9 +812,9 @@ func (c *DocumentController) Content() {
} }
} }
//如果启用了自动发布 //如果启用了自动发布
if auto_release { if autoRelease {
go func(identify string) { go func(identify string) {
models.NewDocument().ReleaseContent(book_id) models.NewDocument().ReleaseContent(bookId)
}(identify) }(identify)
} }
@@ -822,7 +822,7 @@ func (c *DocumentController) Content() {
c.JsonResult(0, "ok", doc) c.JsonResult(0, "ok", doc)
} }
doc, err := models.NewDocument().Find(doc_id) doc, err := models.NewDocument().Find(docId)
if err != nil { if err != nil {
c.JsonResult(6003, "文档不存在") c.JsonResult(6003, "文档不存在")
} }
@@ -883,6 +883,9 @@ func (c *DocumentController) Export() {
} else { } else {
bookResult = isReadable(identify, token, c) bookResult = isReadable(identify, token, c)
} }
if !bookResult.IsDownload {
c.ShowErrorPage(200,"当前项目没有开启导出功能")
}
if !strings.HasPrefix(bookResult.Cover, "http:://") && !strings.HasPrefix(bookResult.Cover, "https:://") { if !strings.HasPrefix(bookResult.Cover, "http:://") && !strings.HasPrefix(bookResult.Cover, "https:://") {
bookResult.Cover = c.BaseUrl() + bookResult.Cover bookResult.Cover = c.BaseUrl() + bookResult.Cover
@@ -911,6 +914,8 @@ func (c *DocumentController) Export() {
c.Ctx.Output.Download(eBookResult.WordPath, bookResult.BookName+".docx") c.Ctx.Output.Download(eBookResult.WordPath, bookResult.BookName+".docx")
c.Abort("200") c.Abort("200")
}else{
c.ShowErrorPage(200,"不支持的文件格式")
} }
c.Abort("404") c.Abort("404")

View File

@@ -47,7 +47,7 @@ func (c *LabelController) Index() {
if c.Member != nil { if c.Member != nil {
member_id = c.Member.MemberId member_id = c.Member.MemberId
} }
search_result, totalCount, err := models.NewBook().FindForLabelToPager(labelName, pageIndex, conf.PageSize, member_id) searchResult, totalCount, err := models.NewBook().FindForLabelToPager(labelName, pageIndex, conf.PageSize, member_id)
if err != nil { if err != nil {
beego.Error(err) beego.Error(err)
@@ -59,7 +59,7 @@ func (c *LabelController) Index() {
} else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
} }
c.Data["Lists"] = search_result c.Data["Lists"] = searchResult
c.Data["LabelName"] = labelName c.Data["LabelName"] = labelName
} }

View File

@@ -15,6 +15,7 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"github.com/lifei6671/mindoc/utils/pagination" "github.com/lifei6671/mindoc/utils/pagination"
"math"
) )
type ManagerController struct { type ManagerController struct {
@@ -633,3 +634,66 @@ func (c *ManagerController) AttachDelete() {
} }
c.JsonResult(0, "ok") c.JsonResult(0, "ok")
} }
//标签列表
func (c *ManagerController) LabelList(){
c.Prepare()
c.TplName = "manager/label_list.tpl"
pageIndex, _ := c.GetInt("page", 1)
labels, totalCount, err := models.NewLabel().FindToPager(pageIndex, conf.PageSize)
if err != nil {
c.ShowErrorPage(50001, err.Error())
}
if totalCount > 0 {
pager := pagination.NewPagination(c.Ctx.Request,totalCount,conf.PageSize)
c.Data["PageHtml"] = pager.HtmlPages()
} else {
c.Data["PageHtml"] = ""
}
c.Data["TotalPages"] = int(math.Ceil(float64(totalCount) / float64(conf.PageSize)))
c.Data["Lists"] = labels
}
//删除标签
func (c *ManagerController) LabelDelete(){
labelId,err := strconv.Atoi(c.Ctx.Input.Param(":id"))
if err != nil {
beego.Error("获取删除标签参数时出错:",err)
c.JsonResult(50001,"参数错误")
}
if labelId <= 0 {
c.JsonResult(50001,"参数错误")
}
label,err := models.NewLabel().FindFirst("label_id",labelId)
if err != nil {
beego.Error("查询标签时出错:",err)
c.JsonResult(50001,"查询标签时出错:" + err.Error())
}
if err := label.Delete();err != nil {
c.JsonResult(50002,"删除失败:" + err.Error())
}else{
c.JsonResult(0,"ok")
}
}

View File

@@ -4,8 +4,8 @@ import (
"github.com/astaxie/beego" "github.com/astaxie/beego"
"github.com/lifei6671/mindoc/conf" "github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/models" "github.com/lifei6671/mindoc/models"
"github.com/lifei6671/mindoc/utils"
"github.com/lifei6671/mindoc/utils/pagination" "github.com/lifei6671/mindoc/utils/pagination"
"regexp"
"strconv" "strconv"
"strings" "strings"
) )
@@ -13,6 +13,7 @@ import (
type SearchController struct { type SearchController struct {
BaseController BaseController
} }
//搜索首页 //搜索首页
func (c *SearchController) Index() { func (c *SearchController) Index() {
c.Prepare() c.Prepare()
@@ -42,7 +43,7 @@ func (c *SearchController) Index() {
return return
} }
if totalCount > 0 { if totalCount > 0 {
pager := pagination.NewPagination(c.Ctx.Request,totalCount,conf.PageSize) pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize)
c.Data["PageHtml"] = pager.HtmlPages() c.Data["PageHtml"] = pager.HtmlPages()
} else { } else {
c.Data["PageHtml"] = "" c.Data["PageHtml"] = ""
@@ -54,27 +55,7 @@ func (c *SearchController) Index() {
if item.Description != "" { if item.Description != "" {
src := item.Description src := item.Description
//将HTML标签全转换成小写 r := []rune(utils.StripTags(item.Description))
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllStringFunc(src, strings.ToLower)
//去除STYLE
re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
src = re.ReplaceAllString(src, "")
//去除SCRIPT
re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
src = re.ReplaceAllString(src, "")
//去除所有尖括号内的HTML代码并换成换行符
re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllString(src, "\n")
//去除连续的换行符
re, _ = regexp.Compile("\\s{2,}")
src = re.ReplaceAllString(src, "\n")
r := []rune(src)
if len(r) > 100 { if len(r) > 100 {
src = string(r[:100]) src = string(r[:100])
@@ -101,35 +82,34 @@ func (c *SearchController) User() {
c.Prepare() c.Prepare()
key := c.Ctx.Input.Param(":key") key := c.Ctx.Input.Param(":key")
keyword := strings.TrimSpace(c.GetString("q")) keyword := strings.TrimSpace(c.GetString("q"))
if key == "" || keyword == ""{ if key == "" || keyword == "" {
c.JsonResult(404,"参数错误") c.JsonResult(404, "参数错误")
} }
book, err := models.NewBookResult().FindByIdentify(key, c.Member.MemberId) book, err := models.NewBookResult().FindByIdentify(key, c.Member.MemberId)
if err != nil { if err != nil {
if err == models.ErrPermissionDenied { if err == models.ErrPermissionDenied {
c.JsonResult(403,"没有权限") c.JsonResult(403, "没有权限")
} }
c.JsonResult(500,"项目不存在") c.JsonResult(500, "项目不存在")
} }
members,err := models.NewMemberRelationshipResult().FindNotJoinUsersByAccount(book.BookId,10,"%"+keyword+"%") members, err := models.NewMemberRelationshipResult().FindNotJoinUsersByAccount(book.BookId, 10, "%"+keyword+"%")
if err != nil { if err != nil {
beego.Error("查询用户列表出错:" + err.Error()) beego.Error("查询用户列表出错:" + err.Error())
c.JsonResult(500,err.Error()) c.JsonResult(500, err.Error())
} }
result := models.SelectMemberResult{} result := models.SelectMemberResult{}
items := make([]models.KeyValueItem,0) items := make([]models.KeyValueItem, 0)
for _,member := range members { for _, member := range members {
item := models.KeyValueItem{} item := models.KeyValueItem{}
item.Id = member.MemberId item.Id = member.MemberId
item.Text = member.Account item.Text = member.Account
items = append(items,item) items = append(items, item)
} }
result.Result = items result.Result = items
c.JsonResult(0,"OK", result) c.JsonResult(0, "OK", result)
} }

View File

@@ -22,6 +22,8 @@ type Book struct {
Identify string `orm:"column(identify);size(100);unique" json:"identify"` Identify string `orm:"column(identify);size(100);unique" json:"identify"`
//是否是自动发布 0 否/1 是 //是否是自动发布 0 否/1 是
AutoRelease int `orm:"column(auto_release);type(int);default(0)" json:"auto_release"` AutoRelease int `orm:"column(auto_release);type(int);default(0)" json:"auto_release"`
//是否开启下载功能 0 是/1 否
IsDownload int `orm:"column(is_download);type(int);default(0)" json:"is_download"`
OrderIndex int `orm:"column(order_index);type(int);default(0)" json:"order_index"` OrderIndex int `orm:"column(order_index);type(int);default(0)" json:"order_index"`
// Description 项目描述. // Description 项目描述.
Description string `orm:"column(description);size(2000)" json:"description"` Description string `orm:"column(description);size(2000)" json:"description"`
@@ -129,7 +131,7 @@ func (m *Book) Update(cols ...string) error {
return err return err
} }
if (m.Label + temp.Label) != "" { if m.Label != "" || temp.Label != ""{
go NewLabel().InsertOrUpdateMulti(m.Label + "," + temp.Label) go NewLabel().InsertOrUpdateMulti(m.Label + "," + temp.Label)
} }
@@ -314,16 +316,16 @@ func (m *Book) FindForHomeToPager(pageIndex, pageSize, member_id int) (books []*
} }
//分页全局搜索. //分页全局搜索.
func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_id int) (books []*BookResult, totalCount int, err error) { func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, memberId int) (books []*BookResult, totalCount int, err error) {
o := orm.NewOrm() o := orm.NewOrm()
keyword = "%" + keyword + "%" keyword = "%" + keyword + "%"
offset := (pageIndex - 1) * pageSize offset := (pageIndex - 1) * pageSize
//如果是登录用户 //如果是登录用户
if member_id > 0 { if memberId > 0 {
sql1 := "SELECT COUNT(*) FROM md_books AS book LEFT JOIN md_relationship AS rel ON rel.book_id = book.book_id AND rel.member_id = ? WHERE (relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ?" sql1 := "SELECT COUNT(*) FROM md_books AS book LEFT JOIN md_relationship AS rel ON rel.book_id = book.book_id AND rel.member_id = ? WHERE (relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ?"
err = o.Raw(sql1, member_id, keyword).QueryRow(&totalCount) err = o.Raw(sql1, memberId, keyword).QueryRow(&totalCount)
if err != nil { if err != nil {
return return
} }
@@ -333,7 +335,7 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
LEFT JOIN md_members AS member ON rel1.member_id = member.member_id LEFT JOIN md_members AS member ON rel1.member_id = member.member_id
WHERE (rel.relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?` WHERE (rel.relationship_id > 0 OR book.privately_owned = 0) AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?`
_, err = o.Raw(sql2, member_id, keyword, offset, pageSize).QueryRows(&books) _, err = o.Raw(sql2, memberId, keyword, offset, pageSize).QueryRows(&books)
return return
@@ -359,12 +361,12 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
} }
//重置文档数量 //重置文档数量
func (m *Book) ResetDocumentNumber(book_id int) { func (m *Book) ResetDocumentNumber(bookId int) {
o := orm.NewOrm() o := orm.NewOrm()
totalCount, err := o.QueryTable(NewDocument().TableNameWithPrefix()).Filter("book_id", book_id).Count() totalCount, err := o.QueryTable(NewDocument().TableNameWithPrefix()).Filter("book_id", bookId).Count()
if err == nil { if err == nil {
o.Raw("UPDATE md_books SET doc_count = ? WHERE book_id = ?", int(totalCount), book_id).Exec() o.Raw("UPDATE md_books SET doc_count = ? WHERE book_id = ?", int(totalCount), bookId).Exec()
} else { } else {
beego.Error(err) beego.Error(err)
} }

View File

@@ -51,6 +51,7 @@ type BookResult struct {
LastModifyText string `json:"last_modify_text"` LastModifyText string `json:"last_modify_text"`
IsDisplayComment bool `json:"is_display_comment"` IsDisplayComment bool `json:"is_display_comment"`
IsDownload bool `json:"is_download"`
} }
func NewBookResult() *BookResult { func NewBookResult() *BookResult {
@@ -174,6 +175,7 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
m.AutoRelease = book.AutoRelease == 1 m.AutoRelease = book.AutoRelease == 1
m.Publisher = book.Publisher m.Publisher = book.Publisher
m.HistoryCount = book.HistoryCount m.HistoryCount = book.HistoryCount
m.IsDownload = book.IsDownload == 0
if book.Theme == "" { if book.Theme == "" {
m.Theme = "default" m.Theme = "default"

View File

@@ -14,7 +14,6 @@ import (
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
"github.com/lifei6671/mindoc/cache" "github.com/lifei6671/mindoc/cache"
"encoding/json" "encoding/json"
"qiniupkg.com/x/errors.v7"
) )
// Document struct. // Document struct.
@@ -65,9 +64,7 @@ func (m *Document) Find(id int) (*Document, error) {
if id <= 0 { if id <= 0 {
return m, ErrInvalidParameter return m, ErrInvalidParameter
} }
if m,err := m.FromCacheById(id); err == nil {
return m,nil
}
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id", id).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id", id).One(m)
@@ -75,7 +72,7 @@ func (m *Document) Find(id int) (*Document, error) {
if err == orm.ErrNoRows { if err == orm.ErrNoRows {
return m, ErrDataNotExist return m, ErrDataNotExist
} }
m.PutToCache()
return m, nil return m, nil
} }
@@ -93,36 +90,16 @@ func (m *Document) InsertOrUpdate(cols ...string) error {
return err return err
} }
m.PutToCache()
return nil return nil
} }
//根据指定字段查询一条文档. //根据指定字段查询一条文档.
func (m *Document) FindByFieldFirst(field string, v interface{}) (*Document, error) { func (m *Document) FindByFieldFirst(field string, v interface{}) (*Document, error) {
if field == "identify" {
if identify,ok := v.(string);ok {
if m,err := m.FromCacheByIdentify(identify);err == nil{
return m,nil
}
}
}else if field == "document_id" {
if id,ok := v.(int); ok && id > 0 {
if m,err := m.FromCacheById(id);err == nil{
return m,nil
}
}
}
o := orm.NewOrm() o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, v).One(m) err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, v).One(m)
if err == nil {
m.PutToCache()
}
return m, err return m, err
} }
@@ -165,7 +142,7 @@ func (m *Document) ReleaseContent(bookId int) {
o := orm.NewOrm() o := orm.NewOrm()
var docs []*Document var docs []*Document
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", bookId).All(&docs, "document_id", "content") _, err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", bookId).All(&docs, "document_id","identify", "content")
if err != nil { if err != nil {
beego.Error("发布失败 => ", err) beego.Error("发布失败 => ", err)
@@ -214,7 +191,12 @@ func (m *Document) ReleaseContent(bookId int) {
beego.Error(fmt.Sprintf("发布失败 => %+v", item), err) beego.Error(fmt.Sprintf("发布失败 => %+v", item), err)
}else { }else {
//当文档发布后,需要清除已缓存的转换文档和文档缓存 //当文档发布后,需要清除已缓存的转换文档和文档缓存
item.PutToCache() if doc,err := NewDocument().Find(item.DocumentId); err == nil {
doc.PutToCache()
}else{
doc.RemoveCache()
}
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(bookId))) os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(bookId)))
} }
} }
@@ -222,38 +204,54 @@ func (m *Document) ReleaseContent(bookId int) {
//将文档写入缓存 //将文档写入缓存
func (m *Document) PutToCache(){ func (m *Document) PutToCache(){
if v,err := json.Marshal(m);err == nil { go func(m Document) {
if m.Identify == "" { if v,err := json.Marshal(&m);err == nil {
if err := cache.Put("Document.Id."+strconv.Itoa(m.DocumentId), v, time.Second*3600); err != nil { if m.Identify == "" {
beego.Info("文档缓存失败:", m)
} if err := cache.Put("Document.Id." + strconv.Itoa(m.DocumentId), v, time.Second*3600); err != nil {
}else{ beego.Info("文档缓存失败:", m.DocumentId)
if err := cache.Put("Document.Identify."+ m.Identify, v, time.Second*3600); err != nil { }
beego.Info("文档缓存失败:", m) }else{
if err := cache.Put("Document.Identify."+ m.Identify, v, time.Second*3600); err != nil {
beego.Info("文档缓存失败:", m.DocumentId)
}
} }
} }
} }(*m)
} }
//清除缓存
func (m *Document) RemoveCache() {
go func(m Document) {
cache.Put("Document.Id." + strconv.Itoa(m.DocumentId), m, time.Second*3600);
if m.Identify != "" {
cache.Put("Document.Identify."+ m.Identify, m, time.Second*3600);
}
}(*m)
}
//从缓存获取 //从缓存获取
func (m *Document) FromCacheById(id int) (*Document,error) { func (m *Document) FromCacheById(id int) (*Document,error) {
b := cache.Get("Document.Id." + strconv.Itoa(id)) b := cache.Get("Document.Id." + strconv.Itoa(id))
if v,ok := b.([]byte); ok { if v,ok := b.([]byte); ok {
beego.Info("从缓存中获取文档信息成功")
if err := json.Unmarshal(v,m);err == nil{ if err := json.Unmarshal(v,m);err == nil{
beego.Info("从缓存中获取文档信息成功",m.DocumentId)
return m,nil return m,nil
} }
} }
return nil,errors.New("Cache not exists") return m.Find(id)
} }
//根据文档标识从缓存中查询文档
func (m *Document) FromCacheByIdentify(identify string) (*Document,error) { func (m *Document) FromCacheByIdentify(identify string) (*Document,error) {
b := cache.Get("Document.Identify." + identify) b := cache.Get("Document.Identify." + identify)
if v,ok := b.([]byte); ok { if v,ok := b.([]byte); ok {
beego.Info("从缓存中获取文档信息成功")
if err := json.Unmarshal(v,m);err == nil{ if err := json.Unmarshal(v,m);err == nil{
beego.Info("从缓存中获取文档信息成功",m.DocumentId)
return m,nil return m,nil
} }
} }
return nil,errors.New("Cache not exists") return m.FindByFieldFirst("identify",identify)
} }
//根据项目ID查询文档列表. //根据项目ID查询文档列表.

View File

@@ -72,6 +72,16 @@ func (m *Label) InsertOrUpdateMulti(labels string) {
} }
} }
} }
//删除标签
func (m *Label) Delete() error {
o := orm.NewOrm()
_,err := o.Raw("DELETE FROM " + m.TableNameWithPrefix() + " WHERE label_id= ?",m.LabelId).Exec()
if err != nil {
return err
}
return nil
}
//分页查找标签. //分页查找标签.
func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label, totalCount int, err error) { func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label, totalCount int, err error) {
@@ -90,3 +100,7 @@ func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label, totalCoun
return return
} }

View File

@@ -9,6 +9,7 @@ import (
type MemberRelationshipResult struct { type MemberRelationshipResult struct {
MemberId int `json:"member_id"` MemberId int `json:"member_id"`
Account string `json:"account"` Account string `json:"account"`
RealName string `json:"real_name"`
Description string `json:"description"` Description string `json:"description"`
Email string `json:"email"` Email string `json:"email"`
Phone string `json:"phone"` Phone string `json:"phone"`
@@ -47,6 +48,7 @@ func (m *MemberRelationshipResult) FromMember(member *Member) *MemberRelationshi
m.Status = member.Status m.Status = member.Status
m.CreateTime = member.CreateTime m.CreateTime = member.CreateTime
m.CreateAt = member.CreateAt m.CreateAt = member.CreateAt
m.RealName = member.RealName
return m return m
} }

View File

@@ -33,6 +33,8 @@ func init() {
beego.Router("/manager/attach/list", &controllers.ManagerController{}, "*:AttachList") beego.Router("/manager/attach/list", &controllers.ManagerController{}, "*:AttachList")
beego.Router("/manager/attach/detailed/:id", &controllers.ManagerController{}, "*:AttachDetailed") beego.Router("/manager/attach/detailed/:id", &controllers.ManagerController{}, "*:AttachDetailed")
beego.Router("/manager/attach/delete", &controllers.ManagerController{}, "post:AttachDelete") beego.Router("/manager/attach/delete", &controllers.ManagerController{}, "post:AttachDelete")
beego.Router("/manager/label/list", &controllers.ManagerController{},"get:LabelList")
beego.Router("/manager/label/delete/:id", &controllers.ManagerController{},"post:LabelDelete")
beego.Router("/setting", &controllers.SettingController{}, "*:Index") beego.Router("/setting", &controllers.SettingController{}, "*:Index")
beego.Router("/setting/password", &controllers.SettingController{}, "*:Password") beego.Router("/setting/password", &controllers.SettingController{}, "*:Password")

31
utils/html.go Normal file
View File

@@ -0,0 +1,31 @@
package utils
import (
"regexp"
"strings"
)
func StripTags(s string) string {
//将HTML标签全转换成小写
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
src := re.ReplaceAllStringFunc(s, strings.ToLower)
//去除STYLE
re, _ = regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
src = re.ReplaceAllString(src, "")
//去除SCRIPT
re, _ = regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
src = re.ReplaceAllString(src, "")
//去除所有尖括号内的HTML代码并换成换行符
re, _ = regexp.Compile("\\<[\\S\\s]+?\\>")
src = re.ReplaceAllString(src, "\n")
//去除连续的换行符
re, _ = regexp.Compile("\\s{2,}")
src = re.ReplaceAllString(src, "\n")
return src
}

View File

@@ -137,6 +137,14 @@
</div> </div>
</div> </div>
</div> </div>
<div class="form-group">
<label for="autoRelease">开启导出</label>
<div class="controls">
<div class="switch switch-small" data-on="primary" data-off="info">
<input type="checkbox" id="isDownload" name="is_download"{{if .Model.IsDownload }} checked{{end}} data-size="small">
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<button type="submit" id="btnSaveBookInfo" class="btn btn-success" data-loading-text="保存中...">保存修改</button> <button type="submit" id="btnSaveBookInfo" class="btn btn-success" data-loading-text="保存中...">保存修改</button>
<span id="form-error-message" class="error-message"></span> <span id="form-error-message" class="error-message"></span>
@@ -301,6 +309,7 @@
window.modalHtml = $("#upload-logo-panel").find(".modal-body").html(); window.modalHtml = $("#upload-logo-panel").find(".modal-body").html();
}); });
$("#autoRelease").bootstrapSwitch(); $("#autoRelease").bootstrapSwitch();
$("#isDownload").bootstrapSwitch();
$('input[name="label"]').tagsinput({ $('input[name="label"]').tagsinput({
confirmKeys: [13,44], confirmKeys: [13,44],

View File

@@ -52,6 +52,7 @@
<div class="list-item" v-for="item in lists"> <div class="list-item" v-for="item in lists">
<img :src="item.avatar" onerror="this.src='/static/images/middle.gif'" class="img-circle" width="34" height="34"> <img :src="item.avatar" onerror="this.src='/static/images/middle.gif'" class="img-circle" width="34" height="34">
<span>${item.account}</span> <span>${item.account}</span>
<span style="font-size: 12px;color: #484848" v-if="item.real_name != ''">[${item.real_name}]</span>
<div class="operate"> <div class="operate">
<template v-if="item.role_id == 0"> <template v-if="item.role_id == 0">
创始人 创始人

View File

@@ -64,6 +64,7 @@
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#shareProject"><i class="fa fa-share-alt" aria-hidden="true"></i> 分享</button> <button type="button" class="btn btn-success" data-toggle="modal" data-target="#shareProject"><i class="fa fa-share-alt" aria-hidden="true"></i> 分享</button>
{{end}} {{end}}
</div> </div>
{{if .Model.IsDownload}}
<div class="dropdown pull-right" style="margin-right: 10px;"> <div class="dropdown pull-right" style="margin-right: 10px;">
<button type="button" class="btn btn-primary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button type="button" class="btn btn-primary" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-cloud-download" aria-hidden="true"></i> 下载 <span class="caret"></span> <i class="fa fa-cloud-download" aria-hidden="true"></i> 下载 <span class="caret"></span>
@@ -75,7 +76,7 @@
<li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "docx"}}" target="_blank">Word</a> </li> <li><a href="{{urlfor "DocumentController.Export" ":key" .Model.Identify "output" "docx"}}" target="_blank">Word</a> </li>
</ul> </ul>
</div> </div>
{{end}}
</div> </div>
</div> </div>
</header> </header>

View File

@@ -31,6 +31,7 @@
<li><a href="{{urlfor "ManagerController.Books" }}" class="item"><i class="fa fa-book" aria-hidden="true"></i> 项目管理</a> </li> <li><a href="{{urlfor "ManagerController.Books" }}" class="item"><i class="fa fa-book" aria-hidden="true"></i> 项目管理</a> </li>
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li class="active"><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li class="active"><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>
<div class="page-right"> <div class="page-right">

View File

@@ -32,6 +32,7 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li class="active"><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li class="active"><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>
<div class="page-right"> <div class="page-right">

View File

@@ -32,6 +32,7 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>
<div class="page-right"> <div class="page-right">

View File

@@ -33,6 +33,7 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>
<div class="page-right"> <div class="page-right">

View File

@@ -31,6 +31,7 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>
<div class="page-right"> <div class="page-right">

View File

@@ -32,6 +32,7 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>标签管理 - Powered by MinDoc</title>
<!-- Bootstrap -->
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet" type="text/css">
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet" type="text/css">
<link href="{{cdncss "/static/css/main.css"}}" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="{{cdnjs "/static/html5shiv/3.7.3/html5shiv.min.js"}}"></script>
<script src="{{cdnjs "/static/respond.js/1.4.2/respond.min.js" }}"></script>
<![endif]-->
</head>
<body>
<div class="manual-reader">
{{template "widgets/header.tpl" .}}
<div class="container manual-body">
<div class="row">
<div class="page-left">
<ul class="menu">
<li><a href="{{urlfor "ManagerController.Index"}}" class="item"><i class="fa fa-dashboard" aria-hidden="true"></i> 仪表盘</a> </li>
<li><a href="{{urlfor "ManagerController.Users" }}" class="item"><i class="fa fa-users" aria-hidden="true"></i> 用户管理</a> </li>
<li><a href="{{urlfor "ManagerController.Books" }}" class="item"><i class="fa fa-book" aria-hidden="true"></i> 项目管理</a> </li>
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li class="active"><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul>
</div>
<div class="page-right">
<div class="m-box">
<div class="box-head">
<strong class="box-title">附件管理</strong>
</div>
</div>
<div class="box-body">
<div class="attach-list" id="attachList">
<table class="table">
<thead>
<tr>
<th width="10%">#</th>
<th width="55%">标签名称</th>
<th width="20%">使用数量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{range $index,$item := .Lists}}
<tr>
<td>{{$item.LabelId}}</td>
<td>{{$item.LabelName}}</td>
<td>{{$item.BookNumber}}</td>
<td>
<button type="button" data-method="delete" class="btn btn-danger btn-sm" data-id="{{$item.LabelId}}" data-loading-text="删除中...">删除</button>
<a href="{{urlfor "LabelController.Index" ":key" $item.LabelName}}" class="btn btn-success btn-sm" target="_blank">详情</a>
</td>
</tr>
{{else}}
<tr><td class="text-center" colspan="6">暂无数据</td></tr>
{{end}}
</tbody>
</table>
<nav class="pagination-container">
{{.PageHtml}}
</nav>
</div>
</div>
</div>
</div>
</div>
{{template "widgets/footer.tpl" .}}
</div>
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}"></script>
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script>
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
<script src="{{cdnjs "/static/layer/layer.js" }}" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#attachList").on("click","button[data-method='delete']",function () {
var id = $(this).attr("data-id");
var $this = $(this);
$(this).button("loading");
$.ajax({
url : "{{urlfor "ManagerController.LabelDelete" ":id" ""}}" + id,
type : "post",
dataType : "json",
success : function (res) {
if(res.errcode === 0){
$this.closest("tr").remove().empty();
}else {
layer.msg(res.message);
}
},
error : function () {
layer.msg("服务器异常");
},
complete : function () {
$this.button("reset");
}
});
});
});
</script>
</body>
</html>

View File

@@ -31,6 +31,7 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li class="active"><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li class="active"><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>

View File

@@ -35,6 +35,8 @@
{{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}} {{/*<li><a href="{{urlfor "ManagerController.Comments" }}" class="item"><i class="fa fa-comments-o" aria-hidden="true"></i> </a> </li>*/}}
<li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li> <li><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
<li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li> <li><a href="{{urlfor "ManagerController.AttachList" }}" class="item"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 附件管理</a> </li>
<li><a href="{{urlfor "ManagerController.LabelList" }}" class="item"><i class="fa fa-bookmark" aria-hidden="true"></i> 标签管理</a> </li>
</ul> </ul>
</div> </div>