mirror of https://github.com/mindoc-org/mindoc.git
feat:实现项目集功能
parent
4702334604
commit
91df6bb024
|
@ -105,6 +105,7 @@ func RegisterModel() {
|
|||
new(models.Team),
|
||||
new(models.TeamMember),
|
||||
new(models.TeamRelationship),
|
||||
new(models.Itemsets),
|
||||
)
|
||||
gob.Register(models.Blog{})
|
||||
gob.Register(models.Document{})
|
||||
|
@ -449,32 +450,33 @@ func RegisterAutoLoadConfig() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//注册错误处理方法.
|
||||
func RegisterError() {
|
||||
func RegisterError() {
|
||||
beego.ErrorHandler("404", func(writer http.ResponseWriter, request *http.Request) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
data :=make(map[string]interface{})
|
||||
data := make(map[string]interface{})
|
||||
data["ErrorCode"] = 404
|
||||
data["ErrorMessage"] = "页面未找到或已删除"
|
||||
|
||||
if err := beego.ExecuteViewPathTemplate(&buf,"errors/error.tpl",beego.BConfig.WebConfig.ViewsPath,data);err == nil {
|
||||
fmt.Fprint(writer,buf.String())
|
||||
if err := beego.ExecuteViewPathTemplate(&buf, "errors/error.tpl", beego.BConfig.WebConfig.ViewsPath, data); err == nil {
|
||||
fmt.Fprint(writer, buf.String())
|
||||
} else {
|
||||
fmt.Fprint(writer,data["ErrorMessage"])
|
||||
fmt.Fprint(writer, data["ErrorMessage"])
|
||||
}
|
||||
})
|
||||
beego.ErrorHandler("401", func(writer http.ResponseWriter, request *http.Request) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
data :=make(map[string]interface{})
|
||||
data := make(map[string]interface{})
|
||||
data["ErrorCode"] = 401
|
||||
data["ErrorMessage"] = "请与 Web 服务器的管理员联系,以确认您是否具有访问所请求资源的权限。"
|
||||
|
||||
if err := beego.ExecuteViewPathTemplate(&buf,"errors/error.tpl",beego.BConfig.WebConfig.ViewsPath,data);err == nil {
|
||||
fmt.Fprint(writer,buf.String())
|
||||
if err := beego.ExecuteViewPathTemplate(&buf, "errors/error.tpl", beego.BConfig.WebConfig.ViewsPath, data); err == nil {
|
||||
fmt.Fprint(writer, buf.String())
|
||||
} else {
|
||||
fmt.Fprint(writer,data["ErrorMessage"])
|
||||
fmt.Fprint(writer, data["ErrorMessage"])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -135,8 +135,18 @@ func initialization() {
|
|||
book.Theme = "default"
|
||||
|
||||
if err := book.Insert(); err != nil {
|
||||
panic("Book.Insert => " + err.Error())
|
||||
os.Exit(0)
|
||||
panic("初始化项目失败 -> " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if !models.NewItemsets().Exist(1) {
|
||||
item := models.NewItemsets()
|
||||
item.ItemName = "默认项目"
|
||||
item.MemberId = 1
|
||||
if err := item.Save(); err != nil {
|
||||
panic("初始化项目集失败 -> " + err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,6 +144,7 @@ func (c *BookController) SaveBook() {
|
|||
enableShare := strings.TrimSpace(c.GetString("enable_share")) == "on"
|
||||
isUseFirstDocument := strings.TrimSpace(c.GetString("is_use_first_document")) == "on"
|
||||
autoSave := strings.TrimSpace(c.GetString("auto_save")) == "on"
|
||||
itemId,_ := c.GetInt("itemId")
|
||||
|
||||
if strings.Count(description, "") > 500 {
|
||||
c.JsonResult(6004, "项目描述不能大于500字")
|
||||
|
@ -157,6 +158,9 @@ func (c *BookController) SaveBook() {
|
|||
c.JsonResult(6005, "最多允许添加10个标签")
|
||||
}
|
||||
}
|
||||
if !models.NewItemsets().Exist(itemId) {
|
||||
c.JsonResult(6006,"项目集不存在")
|
||||
}
|
||||
if editor != "markdown" && editor != "html" {
|
||||
editor = "markdown"
|
||||
}
|
||||
|
@ -170,6 +174,7 @@ func (c *BookController) SaveBook() {
|
|||
book.HistoryCount = historyCount
|
||||
book.IsDownload = 0
|
||||
book.BookPassword = c.GetString("bPassword")
|
||||
book.ItemId = itemId
|
||||
|
||||
if autoRelease {
|
||||
book.AutoRelease = 1
|
||||
|
@ -432,6 +437,7 @@ func (c *BookController) Create() {
|
|||
description := strings.TrimSpace(c.GetString("description", ""))
|
||||
privatelyOwned, _ := strconv.Atoi(c.GetString("privately_owned"))
|
||||
commentStatus := c.GetString("comment_status")
|
||||
itemId, _ := c.GetInt("itemId")
|
||||
|
||||
if bookName == "" {
|
||||
c.JsonResult(6001, "项目名称不能为空")
|
||||
|
@ -451,6 +457,9 @@ func (c *BookController) Create() {
|
|||
if privatelyOwned != 0 && privatelyOwned != 1 {
|
||||
privatelyOwned = 1
|
||||
}
|
||||
if !models.NewItemsets().Exist(itemId) {
|
||||
c.JsonResult(6005, "项目集不存在")
|
||||
}
|
||||
if commentStatus != "open" && commentStatus != "closed" && commentStatus != "group_only" && commentStatus != "registered_only" {
|
||||
commentStatus = "closed"
|
||||
}
|
||||
|
@ -503,6 +512,7 @@ func (c *BookController) Create() {
|
|||
book.IsUseFirstDocument = 1
|
||||
book.IsDownload = 1
|
||||
book.AutoRelease = 0
|
||||
book.ItemId = itemId
|
||||
|
||||
book.Editor = "markdown"
|
||||
book.Theme = "default"
|
||||
|
@ -563,6 +573,7 @@ func (c *BookController) Import() {
|
|||
identify := strings.TrimSpace(c.GetString("identify"))
|
||||
description := strings.TrimSpace(c.GetString("description", ""))
|
||||
privatelyOwned, _ := strconv.Atoi(c.GetString("privately_owned"))
|
||||
itemId, _ := c.GetInt("itemId")
|
||||
|
||||
if bookName == "" {
|
||||
c.JsonResult(6001, "项目名称不能为空")
|
||||
|
@ -576,6 +587,9 @@ func (c *BookController) Import() {
|
|||
if ok, err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`, identify); !ok || err != nil {
|
||||
c.JsonResult(6003, "项目标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头")
|
||||
}
|
||||
if !models.NewItemsets().Exist(itemId) {
|
||||
c.JsonResult(6007, "项目集不存在")
|
||||
}
|
||||
if strings.Count(identify, "") > 50 {
|
||||
c.JsonResult(6004, "文档标识不能超过50字")
|
||||
}
|
||||
|
@ -612,6 +626,7 @@ func (c *BookController) Import() {
|
|||
book.MemberId = c.Member.MemberId
|
||||
book.CommentCount = 0
|
||||
book.Version = time.Now().Unix()
|
||||
book.ItemId = itemId
|
||||
|
||||
book.Editor = "markdown"
|
||||
book.Theme = "default"
|
||||
|
@ -896,7 +911,7 @@ func (c *BookController) TeamDelete() {
|
|||
teamId, _ := c.GetInt("teamId")
|
||||
|
||||
if teamId <= 0 {
|
||||
c.JsonResult(5001,"参数错误")
|
||||
c.JsonResult(5001, "参数错误")
|
||||
}
|
||||
book, err := c.IsPermission()
|
||||
|
||||
|
@ -915,6 +930,7 @@ func (c *BookController) TeamDelete() {
|
|||
c.JsonResult(0, "OK")
|
||||
}
|
||||
|
||||
//团队搜索.
|
||||
func (c *BookController) TeamSearch() {
|
||||
c.Prepare()
|
||||
|
||||
|
@ -928,7 +944,22 @@ func (c *BookController) TeamSearch() {
|
|||
searchResult, err := models.NewTeamRelationship().FindNotJoinBookByBookIdentify(book.BookId, keyword, 10)
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(500, err.Error())
|
||||
c.JsonResult(500, err.Error(), searchResult)
|
||||
}
|
||||
c.JsonResult(0, "OK", searchResult)
|
||||
|
||||
}
|
||||
|
||||
//项目集搜索.
|
||||
func (c *BookController) ItemsetsSearch() {
|
||||
c.Prepare()
|
||||
|
||||
keyword := strings.TrimSpace(c.GetString("q"))
|
||||
|
||||
searchResult, err := models.NewItemsets().FindItemsetsByName(keyword, 10)
|
||||
|
||||
if err != nil {
|
||||
c.JsonResult(500, err.Error(), searchResult)
|
||||
}
|
||||
c.JsonResult(0, "OK", searchResult)
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/lifei6671/mindoc/models"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/lifei6671/mindoc/utils/pagination"
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
type ItemsetsController struct {
|
||||
BaseController
|
||||
}
|
||||
func (c *ItemsetsController) Prepare() {
|
||||
c.BaseController.Prepare()
|
||||
|
||||
//如果没有开启你们访问则跳转到登录
|
||||
if !c.EnableAnonymous && c.Member == nil {
|
||||
c.Redirect(conf.URLFor("AccountController.Login"), 302)
|
||||
return
|
||||
}
|
||||
}
|
||||
func (c *ItemsetsController) Index() {
|
||||
c.Prepare()
|
||||
c.TplName = "items/index.tpl"
|
||||
pageIndex, _ := c.GetInt("page", 0)
|
||||
|
||||
items, totalCount, err := models.NewItemsets().FindToPager(pageIndex, conf.PageSize)
|
||||
|
||||
if err != nil && err != orm.ErrNoRows {
|
||||
c.ShowErrorPage(500, err.Error())
|
||||
}
|
||||
c.Data["TotalPages"] = pageIndex
|
||||
if err == orm.ErrNoRows || len(items) <= 0 {
|
||||
c.Data["Lists"] = items
|
||||
c.Data["PageHtml"] = ""
|
||||
return
|
||||
}
|
||||
|
||||
if totalCount > 0 {
|
||||
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
|
||||
c.Data["PageHtml"] = pager.HtmlPages()
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
|
||||
c.Data["Lists"] = items
|
||||
}
|
||||
|
||||
func (c *ItemsetsController) List() {
|
||||
c.Prepare()
|
||||
c.TplName = "items/list.tpl"
|
||||
itemKey := c.Ctx.Input.Param(":key")
|
||||
pageIndex, _ := c.GetInt("page", 1)
|
||||
|
||||
if itemKey == "" {
|
||||
c.Abort("404")
|
||||
}
|
||||
item, err := models.NewItemsets().FindFirst(itemKey)
|
||||
|
||||
if err != nil {
|
||||
if err == orm.ErrNoRows {
|
||||
c.Abort("404")
|
||||
} else {
|
||||
beego.Error(err)
|
||||
c.Abort("500")
|
||||
}
|
||||
}
|
||||
memberId := 0
|
||||
if c.Member != nil {
|
||||
memberId = c.Member.MemberId
|
||||
}
|
||||
searchResult, totalCount, err := models.NewItemsets().FindItemsetsByItemKey(itemKey, pageIndex, conf.PageSize, memberId)
|
||||
|
||||
if err != nil && err != orm.ErrNoRows {
|
||||
c.ShowErrorPage(500, "查询文档列表时出错")
|
||||
}
|
||||
if totalCount > 0 {
|
||||
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
|
||||
c.Data["PageHtml"] = pager.HtmlPages()
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
c.Data["Lists"] = searchResult
|
||||
|
||||
c.Data["Model"] = item
|
||||
}
|
|
@ -1073,6 +1073,8 @@ func (c *ManagerController) TeamSearchBook() {
|
|||
c.JsonResult(0, "OK", searchResult)
|
||||
|
||||
}
|
||||
|
||||
//删除团队项目.
|
||||
func (c *ManagerController) TeamBookDelete() {
|
||||
c.Prepare()
|
||||
teamRelationshipId, _ := c.GetInt("teamRelId")
|
||||
|
@ -1088,3 +1090,78 @@ func (c *ManagerController) TeamBookDelete() {
|
|||
}
|
||||
c.JsonResult(0, "OK")
|
||||
}
|
||||
|
||||
//项目集列表.
|
||||
func (c *ManagerController) Itemsets() {
|
||||
c.Prepare()
|
||||
c.TplName = "manager/itemsets.tpl"
|
||||
pageIndex, _ := c.GetInt("page", 0)
|
||||
|
||||
items, totalCount, err := models.NewItemsets().FindToPager(pageIndex, conf.PageSize)
|
||||
|
||||
if err != nil && err != orm.ErrNoRows {
|
||||
c.ShowErrorPage(500, err.Error())
|
||||
}
|
||||
if err == orm.ErrNoRows || len(items) <= 0 {
|
||||
c.Data["Lists"] = items
|
||||
c.Data["PageHtml"] = ""
|
||||
return
|
||||
}
|
||||
|
||||
if totalCount > 0 {
|
||||
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
|
||||
c.Data["PageHtml"] = pager.HtmlPages()
|
||||
} else {
|
||||
c.Data["PageHtml"] = ""
|
||||
}
|
||||
|
||||
c.Data["Lists"] = items
|
||||
|
||||
|
||||
}
|
||||
|
||||
//编辑或添加项目集.
|
||||
func (c *ManagerController) ItemsetsEdit() {
|
||||
c.Prepare()
|
||||
itemId, _ := c.GetInt("itemId")
|
||||
itemName := c.GetString("itemName")
|
||||
itemKey := c.GetString("itemKey")
|
||||
if itemName == "" || itemKey == "" {
|
||||
c.JsonResult(5001, "参数错误")
|
||||
}
|
||||
var item *models.Itemsets
|
||||
var err error
|
||||
if itemId > 0 {
|
||||
if item, err = models.NewItemsets().First(itemId); err != nil {
|
||||
if err == orm.ErrNoRows {
|
||||
c.JsonResult(5002, "项目集不存在")
|
||||
} else {
|
||||
c.JsonResult(5003, "查询项目集出错")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
item = models.NewItemsets()
|
||||
}
|
||||
|
||||
item.ItemKey = itemKey
|
||||
item.ItemName = itemName
|
||||
item.MemberId = c.Member.MemberId
|
||||
item.ModifyAt = c.Member.MemberId
|
||||
|
||||
if err := item.Save(); err != nil {
|
||||
c.JsonResult(5004, err.Error())
|
||||
}
|
||||
|
||||
c.JsonResult(0, "OK")
|
||||
}
|
||||
|
||||
//删除项目集.
|
||||
func (c *ManagerController) ItemsetsDelete() {
|
||||
c.Prepare()
|
||||
itemId, _ := c.GetInt("itemId")
|
||||
|
||||
if err := models.NewItemsets().Delete(itemId); err != nil {
|
||||
c.JsonResult(5001, err.Error())
|
||||
}
|
||||
c.JsonResult(0, "OK")
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ type Book struct {
|
|||
BookId int `orm:"pk;auto;unique;column(book_id)" json:"book_id"`
|
||||
// BookName 项目名称.
|
||||
BookName string `orm:"column(book_name);size(500)" json:"book_name"`
|
||||
//所属项目集
|
||||
ItemId int `orm:"column(item_id);type(int);default(1)" json:"item_id"`
|
||||
// Identify 项目唯一标识.
|
||||
Identify string `orm:"column(identify);size(100);unique" json:"identify"`
|
||||
//是否是自动发布 0 否/1 是
|
||||
|
@ -112,6 +114,9 @@ func (book *Book) Insert() error {
|
|||
o := orm.NewOrm()
|
||||
// o.Begin()
|
||||
book.BookName = utils.StripTags(book.BookName)
|
||||
if book.ItemId <= 0 {
|
||||
book.ItemId = 1
|
||||
}
|
||||
_, err := o.Insert(book)
|
||||
|
||||
if err == nil {
|
||||
|
@ -125,7 +130,7 @@ func (book *Book) Insert() error {
|
|||
relationship.MemberId = book.MemberId
|
||||
err = relationship.Insert()
|
||||
if err != nil {
|
||||
logs.Error("插入项目与用户关联 => ", err)
|
||||
logs.Error("插入项目与用户关联 -> ", err)
|
||||
//o.Rollback()
|
||||
return err
|
||||
}
|
||||
|
@ -435,7 +440,7 @@ func (book *Book) ThoroughDeleteBook(id int) error {
|
|||
o.Rollback()
|
||||
return err
|
||||
}
|
||||
_,err = o.Raw(fmt.Sprintf("DELETE FROM %s WHERE book_id=?",NewTeamRelationship().TableNameWithPrefix()), book.BookId).Exec()
|
||||
_, err = o.Raw(fmt.Sprintf("DELETE FROM %s WHERE book_id=?", NewTeamRelationship().TableNameWithPrefix()), book.BookId).Exec()
|
||||
if err != nil {
|
||||
o.Rollback()
|
||||
return err
|
||||
|
|
|
@ -33,6 +33,8 @@ var (
|
|||
type BookResult struct {
|
||||
BookId int `json:"book_id"`
|
||||
BookName string `json:"book_name"`
|
||||
ItemId int `json:"item_id"`
|
||||
ItemName string `json:"item_name"`
|
||||
Identify string `json:"identify"`
|
||||
OrderIndex int `json:"order_index"`
|
||||
Description string `json:"description"`
|
||||
|
@ -203,6 +205,7 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
|
|||
m.HistoryCount = book.HistoryCount
|
||||
m.IsDownload = book.IsDownload == 0
|
||||
m.AutoSave = book.AutoSave == 1
|
||||
m.ItemId = book.ItemId
|
||||
|
||||
if book.Theme == "" {
|
||||
m.Theme = "default"
|
||||
|
@ -224,6 +227,11 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
|
|||
m.LastModifyText = member2.Account + " 于 " + doc.ModifyTime.Local().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
if m.ItemId > 0 {
|
||||
if item,err := NewItemsets().First(m.ItemId); err == nil {
|
||||
m.ItemName = item.ItemName
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
"github.com/lifei6671/mindoc/conf"
|
||||
"github.com/astaxie/beego/orm"
|
||||
"github.com/astaxie/beego"
|
||||
"errors"
|
||||
"github.com/lifei6671/mindoc/utils/cryptil"
|
||||
)
|
||||
|
||||
//项目集
|
||||
type Itemsets struct {
|
||||
ItemId int `orm:"column(item_id);pk;auto;unique" json:"item_id"`
|
||||
ItemName string `orm:"column(item_name);size(500)" json:"item_name"`
|
||||
ItemKey string `orm:"column(item_key);size(200);unique" json:"item_key"`
|
||||
Description string `orm:"column(description);type(text);null" json:"description"`
|
||||
MemberId int `orm:"column(member_id);size(100)" json:"member_id"`
|
||||
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
|
||||
ModifyTime time.Time `orm:"column(modify_time);type(datetime);null;auto_now" json:"modify_time"`
|
||||
ModifyAt int `orm:"column(modify_at);type(int)" json:"modify_at"`
|
||||
|
||||
BookNumber int `orm:"-" json:"book_number"`
|
||||
CreateTimeString string `orm:"-" json:"create_time_string"`
|
||||
}
|
||||
|
||||
// TableName 获取对应数据库表名.
|
||||
func (item *Itemsets) TableName() string {
|
||||
return "itemsets"
|
||||
}
|
||||
|
||||
// TableEngine 获取数据使用的引擎.
|
||||
func (item *Itemsets) TableEngine() string {
|
||||
return "INNODB"
|
||||
}
|
||||
func (item *Itemsets) TableNameWithPrefix() string {
|
||||
return conf.GetDatabasePrefix() + item.TableName()
|
||||
}
|
||||
|
||||
func (item *Itemsets) QueryTable() orm.QuerySeter {
|
||||
return orm.NewOrm().QueryTable(item.TableNameWithPrefix())
|
||||
}
|
||||
|
||||
func NewItemsets() *Itemsets {
|
||||
return &Itemsets{}
|
||||
}
|
||||
|
||||
func (item *Itemsets) First(itemId int) (*Itemsets, error) {
|
||||
if itemId <= 0 {
|
||||
return nil, ErrInvalidParameter
|
||||
}
|
||||
err := item.QueryTable().Filter("item_id", itemId).One(item)
|
||||
if err != nil {
|
||||
beego.Error("查询项目集失败 -> item_id=", itemId, err)
|
||||
} else {
|
||||
item.Include()
|
||||
}
|
||||
return item, err
|
||||
}
|
||||
|
||||
func (item *Itemsets) FindFirst(itemKey string) (*Itemsets,error) {
|
||||
err := item.QueryTable().Filter("item_key",itemKey).One(item)
|
||||
if err != nil {
|
||||
beego.Error("查询项目集失败 -> itemKey=", itemKey, err)
|
||||
} else {
|
||||
item.Include()
|
||||
}
|
||||
return item,err
|
||||
}
|
||||
|
||||
func (item *Itemsets) Exist(itemId int) bool {
|
||||
return item.QueryTable().Filter("item_id", itemId).Exist()
|
||||
}
|
||||
|
||||
//保存
|
||||
func (item *Itemsets) Save() (err error) {
|
||||
|
||||
if item.ItemName == "" {
|
||||
return errors.New("项目集名称不能为空")
|
||||
}
|
||||
if item.ItemKey == "" {
|
||||
item.ItemKey = cryptil.NewRandChars(16)
|
||||
}
|
||||
|
||||
if item.QueryTable().Filter("item_id__ne", item.ItemId).Filter("item_key", item.ItemKey).Exist() {
|
||||
return errors.New("项目集标识已存在")
|
||||
}
|
||||
if item.ItemId > 0 {
|
||||
_, err = orm.NewOrm().Update(item)
|
||||
} else {
|
||||
_, err = orm.NewOrm().Insert(item)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//删除.
|
||||
func (item *Itemsets) Delete(itemId int) (err error) {
|
||||
if itemId <= 0 {
|
||||
return ErrInvalidParameter
|
||||
}
|
||||
if itemId == 1 {
|
||||
return errors.New("默认项目集不能删除")
|
||||
}
|
||||
if !item.Exist(itemId) {
|
||||
return errors.New("项目集不存在")
|
||||
}
|
||||
o := orm.NewOrm()
|
||||
if err := o.Begin(); err != nil {
|
||||
beego.Error("开启事物失败 ->", err)
|
||||
return err
|
||||
}
|
||||
_, err = o.QueryTable(item.TableNameWithPrefix()).Filter("item_id", itemId).Delete()
|
||||
if err != nil {
|
||||
beego.Error("删除项目集失败 -> item_id=", itemId, err)
|
||||
o.Rollback()
|
||||
}
|
||||
_, err = o.Raw("update md_books set item_id=1 where item_id=?;", itemId).Exec()
|
||||
if err != nil {
|
||||
beego.Error("删除项目集失败 -> item_id=", itemId, err)
|
||||
o.Rollback()
|
||||
}
|
||||
|
||||
return o.Commit()
|
||||
}
|
||||
|
||||
func (item *Itemsets) Include() (*Itemsets, error) {
|
||||
|
||||
item.CreateTimeString = item.CreateTime.Format("2006-01-02 15:04:05")
|
||||
|
||||
i, err := NewBook().QueryTable().Filter("item_id", item.ItemId).Count()
|
||||
if err != nil && err != orm.ErrNoRows {
|
||||
return item, err
|
||||
}
|
||||
item.BookNumber = int(i)
|
||||
|
||||
return item, nil
|
||||
}
|
||||
|
||||
//分页查询.
|
||||
func (item *Itemsets) FindToPager(pageIndex, pageSize int) (list []*Itemsets, totalCount int, err error) {
|
||||
|
||||
offset := (pageIndex - 1) * pageSize
|
||||
|
||||
_, err = item.QueryTable().OrderBy("-item_id").Offset(offset).Limit(pageSize).All(&list)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c, err := item.QueryTable().Count()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
totalCount = int(c)
|
||||
|
||||
for _, item := range list {
|
||||
item.Include()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//根据项目集名称查询.
|
||||
func (item *Itemsets) FindItemsetsByName(name string, limit int) (*SelectMemberResult, error) {
|
||||
result := SelectMemberResult{}
|
||||
|
||||
var itemsets []*Itemsets
|
||||
var err error
|
||||
if name == "" {
|
||||
_, err = item.QueryTable().Limit(limit).All(&itemsets)
|
||||
|
||||
} else {
|
||||
_, err = item.QueryTable().Filter("item_name__icontains", name).Limit(limit).All(&itemsets)
|
||||
}
|
||||
if err != nil {
|
||||
beego.Error("查询项目集失败 ->", err)
|
||||
return &result, err
|
||||
}
|
||||
|
||||
items := make([]KeyValueItem, 0)
|
||||
|
||||
for _, m := range itemsets {
|
||||
item := KeyValueItem{}
|
||||
item.Id = m.ItemId
|
||||
item.Text = m.ItemName
|
||||
items = append(items, item)
|
||||
}
|
||||
result.Result = items
|
||||
|
||||
return &result, err
|
||||
}
|
||||
|
||||
//根据项目集标识查询项目集的项目列表.
|
||||
func (item *Itemsets) FindItemsetsByItemKey(key string, pageIndex, pageSize, memberId int) (books []*BookResult, totalCount int, err error){
|
||||
o := orm.NewOrm()
|
||||
|
||||
err = item.QueryTable().Filter("item_key",key).One(item)
|
||||
|
||||
if err != nil {
|
||||
return nil,0,err
|
||||
}
|
||||
offset := (pageIndex - 1) * pageSize
|
||||
//如果是登录用户
|
||||
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 = ?
|
||||
left join (select *
|
||||
from (select book_id,team_member_id,role_id
|
||||
from md_team_relationship as mtr
|
||||
left join md_team_member as mtm on mtm.team_id=mtr.team_id and mtm.member_id=? order by role_id desc )as t group by t.book_id) as team on team.book_id = book.book_id
|
||||
WHERE book.item_id = ? AND (relationship_id > 0 OR book.privately_owned = 0 or team.team_member_id > 0)`
|
||||
|
||||
err = o.Raw(sql1, memberId, memberId, item.ItemId).QueryRow(&totalCount)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sql2 := `SELECT book.*,rel1.*,member.account AS create_name FROM md_books AS book
|
||||
LEFT JOIN md_relationship AS rel ON rel.book_id = book.book_id AND rel.member_id = ?
|
||||
left join (select * from (select book_id,team_member_id,role_id
|
||||
from md_team_relationship as mtr
|
||||
left join md_team_member as mtm on mtm.team_id=mtr.team_id and mtm.member_id=? order by role_id desc )as t group by t.book_id) as team
|
||||
on team.book_id = book.book_id
|
||||
LEFT JOIN md_relationship AS rel1 ON rel1.book_id = book.book_id AND rel1.role_id = 0
|
||||
LEFT JOIN md_members AS member ON rel1.member_id = member.member_id
|
||||
WHERE book.item_id = ? AND (rel.relationship_id > 0 OR book.privately_owned = 0 or team.team_member_id > 0)
|
||||
ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?`
|
||||
|
||||
_, err = o.Raw(sql2, memberId, memberId, item.ItemId, offset, pageSize).QueryRows(&books)
|
||||
|
||||
return
|
||||
|
||||
} else {
|
||||
count, err1 := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("privately_owned", 0).Filter("item_id", item.ItemId).Count()
|
||||
|
||||
if err1 != nil {
|
||||
err = err1
|
||||
return
|
||||
}
|
||||
totalCount = int(count)
|
||||
|
||||
sql := `SELECT book.*,rel.*,member.account AS create_name FROM md_books AS book
|
||||
LEFT JOIN md_relationship AS rel ON rel.book_id = book.book_id AND rel.role_id = 0
|
||||
LEFT JOIN md_members AS member ON rel.member_id = member.member_id
|
||||
WHERE book.item_id = ? AND book.privately_owned = 0 ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?`
|
||||
|
||||
_, err = o.Raw(sql, item.ItemId, offset, pageSize).QueryRows(&books)
|
||||
|
||||
return
|
||||
|
||||
}
|
||||
}
|
|
@ -57,6 +57,10 @@ func init() {
|
|||
beego.Router("/manager/team/book/delete", &controllers.ManagerController{}, "POST:TeamBookDelete")
|
||||
beego.Router("/manager/team/book/search", &controllers.ManagerController{}, "*:TeamSearchBook")
|
||||
|
||||
beego.Router("/manager/itemsets", &controllers.ManagerController{},"*:Itemsets")
|
||||
beego.Router("/manager/itemsets/edit", &controllers.ManagerController{},"post:ItemsetsEdit")
|
||||
beego.Router("/manager/itemsets/delete", &controllers.ManagerController{},"post:ItemsetsDelete")
|
||||
|
||||
|
||||
beego.Router("/setting", &controllers.SettingController{}, "*:Index")
|
||||
beego.Router("/setting/password", &controllers.SettingController{}, "*:Password")
|
||||
|
@ -72,6 +76,8 @@ func init() {
|
|||
|
||||
|
||||
beego.Router("/book/create", &controllers.BookController{}, "*:Create")
|
||||
beego.Router("/book/itemsets/search", &controllers.BookController{}, "*:ItemsetsSearch")
|
||||
|
||||
beego.Router("/book/users/create", &controllers.BookMemberController{}, "post:AddMember")
|
||||
beego.Router("/book/users/change", &controllers.BookMemberController{}, "post:ChangeRole")
|
||||
beego.Router("/book/users/delete", &controllers.BookMemberController{}, "post:RemoveMember")
|
||||
|
@ -139,4 +145,8 @@ func init() {
|
|||
|
||||
beego.Router("/tag/:key", &controllers.LabelController{}, "get:Index")
|
||||
beego.Router("/tags", &controllers.LabelController{}, "get:List")
|
||||
|
||||
beego.Router("/items", &controllers.ItemsetsController{},"get:Index")
|
||||
beego.Router("/items/:key", &controllers.ItemsetsController{},"get:List")
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ import (
|
|||
"crypto/rand"
|
||||
)
|
||||
|
||||
var stdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
|
||||
|
||||
//对称加密与解密之加密【从Beego中提取出来的】
|
||||
//@param value 需要加密的字符串
|
||||
//@param secret 加密密钥
|
||||
|
@ -71,7 +73,6 @@ func Sha1Crypt(str string, salt ...interface{}) (CryptStr string) {
|
|||
return fmt.Sprintf("%x", sha1.Sum([]byte(str)))
|
||||
}
|
||||
|
||||
|
||||
//生成Guid字串
|
||||
func UniqueId() string {
|
||||
b := make([]byte, 48)
|
||||
|
@ -80,4 +81,35 @@ func UniqueId() string {
|
|||
return ""
|
||||
}
|
||||
return Md5Crypt(base64.URLEncoding.EncodeToString(b))
|
||||
}
|
||||
}
|
||||
|
||||
//生成指定长度的字符串.
|
||||
func NewRandChars(length int) string {
|
||||
if length == 0 {
|
||||
return ""
|
||||
}
|
||||
clen := len(stdChars)
|
||||
if clen < 2 || clen > 256 {
|
||||
panic("Wrong charset length for NewLenChars()")
|
||||
}
|
||||
maxrb := 255 - (256 % clen)
|
||||
b := make([]byte, length)
|
||||
r := make([]byte, length+(length/4)) // storage for random bytes.
|
||||
i := 0
|
||||
for {
|
||||
if _, err := rand.Read(r); err != nil {
|
||||
panic("Error reading random bytes: " + err.Error())
|
||||
}
|
||||
for _, rb := range r {
|
||||
c := int(rb)
|
||||
if c > maxrb {
|
||||
continue // Skip this number to avoid modulo bias.
|
||||
}
|
||||
b[i] = stdChars[c%clen]
|
||||
i++
|
||||
if i == length {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{cdncss "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/css/fileinput.min.css"}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{cdncss "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/themes/explorer-fa/theme.css"}}" rel="stylesheet" type="text/css">
|
||||
<link href="{{cdncss "/static/select2/4.0.5/css/select2.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/css/main.css" "version"}}" 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:// -->
|
||||
|
@ -137,8 +138,19 @@
|
|||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<div class="pull-left" style="width: 620px">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="标题(不超过100字)" name="book_name" id="bookName">
|
||||
<div class="form-group required">
|
||||
<label class="text-label col-sm-2">项目集</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="js-data-example-ajax-add form-control" multiple="multiple" name="itemId" id="itemId"></select>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="form-group required">
|
||||
<label class="text-label col-sm-2">项目标题</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" class="form-control" placeholder="标题(不超过100字)" name="book_name" id="bookName">
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="pull-left" style="padding: 7px 5px 6px 0">
|
||||
|
@ -194,6 +206,10 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<div class="form-group required">
|
||||
<label class="text-label">项目集</label>
|
||||
<select class="js-data-example-ajax-import form-control" multiple="multiple" name="itemId"></select>
|
||||
</div>
|
||||
<div class="form-group required">
|
||||
<label class="text-label">项目标题</label>
|
||||
<input type="text" class="form-control" placeholder="项目标题(不超过100字)" name="book_name" maxlength="100" value="">
|
||||
|
@ -272,6 +288,8 @@
|
|||
<script src="{{cdnjs "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/fileinput.min.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/bootstrap/plugins/bootstrap-fileinput/4.4.7/js/locales/zh.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/layer/layer.js"}}" type="text/javascript" ></script>
|
||||
<script src="{{cdnjs "/static/select2/4.0.5/js/select2.full.min.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/select2/4.0.5/js/i18n/zh-CN.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/js/main.js"}}" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
/**
|
||||
|
@ -400,6 +418,28 @@
|
|||
$("#addBookDialogModal").on("show.bs.modal",function () {
|
||||
window.bookDialogModal = $(this).find("#addBookDialogForm").html();
|
||||
drawBookCover("bookCover","默认封面");
|
||||
$('.js-data-example-ajax-add').select2({
|
||||
language: "zh-CN",
|
||||
minimumInputLength : 1,
|
||||
minimumResultsForSearch: Infinity,
|
||||
maximumSelectionLength:1,
|
||||
width : "100%",
|
||||
ajax: {
|
||||
url: '{{urlfor "BookController.ItemsetsSearch"}}',
|
||||
dataType: 'json',
|
||||
data: function (params) {
|
||||
return {
|
||||
q: params.term, // search term
|
||||
page: params.page
|
||||
};
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
return {
|
||||
results : data.data.results
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}).on("hidden.bs.modal",function () {
|
||||
$(this).find("#addBookDialogForm").html(window.bookDialogModal);
|
||||
});
|
||||
|
@ -429,6 +469,28 @@
|
|||
return book;
|
||||
}
|
||||
});
|
||||
$('.js-data-example-ajax-import').select2({
|
||||
language: "zh-CN",
|
||||
minimumInputLength : 1,
|
||||
minimumResultsForSearch: Infinity,
|
||||
maximumSelectionLength:1,
|
||||
width : "100%",
|
||||
ajax: {
|
||||
url: '{{urlfor "BookController.ItemsetsSearch"}}',
|
||||
dataType: 'json',
|
||||
data: function (params) {
|
||||
return {
|
||||
q: params.term, // search term
|
||||
page: params.page
|
||||
};
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
return {
|
||||
results : data.data.results
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}).on("hidden.bs.modal",function () {
|
||||
$(this).find("#importBookDialogForm").html(window.importBookDialogModal);
|
||||
});
|
||||
|
@ -439,7 +501,10 @@
|
|||
$("body").on("click","#btnSaveDocument",function () {
|
||||
var $this = $(this);
|
||||
|
||||
|
||||
var itemId = $("#itemId").val();
|
||||
if (itemId <= 0) {
|
||||
return showError("请选择项目集")
|
||||
}
|
||||
var bookName = $.trim($("#bookName").val());
|
||||
if (bookName === "") {
|
||||
return showError("项目标题不能为空")
|
||||
|
@ -504,6 +569,10 @@
|
|||
console.log("aa");
|
||||
var $then = $(this).parents("#importBookDialogForm");
|
||||
|
||||
var itemId = $then.find("input[name='itemId']").val();
|
||||
if (itemId <= 0) {
|
||||
return showError("请选择项目集")
|
||||
}
|
||||
|
||||
var bookName = $.trim($then.find("input[name='book_name']").val());
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
<link href="{{cdncss "/static/cropper/2.3.4/cropper.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/bootstrap/plugins/tagsinput/bootstrap-tagsinput.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/bootstrap/plugins/bootstrap-switch/css/bootstrap3//bootstrap-switch.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/select2/4.0.5/css/select2.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/css/main.css" "version"}}" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
@ -60,6 +61,12 @@
|
|||
<input type="text" class="form-control" value="{{urlfor "DocumentController.Index" ":key" .Model.Identify}}" placeholder="项目唯一标识" disabled>
|
||||
<p class="text">项目标识用来标记项目的唯一性,不可修改。</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>项目集</label>
|
||||
<select class="js-data-example-ajax form-control" multiple="multiple" name="itemId">
|
||||
<option value="{{.Model.ItemId}}" selected="selected">{{.Model.ItemName}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>历史记录数量</label>
|
||||
<input type="text" class="form-control" name="history_count" value="{{.Model.HistoryCount}}" placeholder="历史记录数量">
|
||||
|
@ -312,6 +319,8 @@
|
|||
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/bootstrap/plugins/tagsinput/bootstrap-tagsinput.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/bootstrap/plugins/bootstrap-switch/js/bootstrap-switch.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/select2/4.0.5/js/select2.full.min.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/select2/4.0.5/js/i18n/zh-CN.js"}}"></script>
|
||||
<script src="{{cdnjs "/static/js/main.js"}}" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
|
@ -431,7 +440,28 @@
|
|||
$("#btnTransferBook").button("reset");
|
||||
}
|
||||
});
|
||||
|
||||
$('.js-data-example-ajax').select2({
|
||||
language: "zh-CN",
|
||||
minimumInputLength : 1,
|
||||
minimumResultsForSearch: Infinity,
|
||||
maximumSelectionLength:1,
|
||||
width : "100%",
|
||||
ajax: {
|
||||
url: '{{urlfor "BookController.ItemsetsSearch"}}',
|
||||
dataType: 'json',
|
||||
data: function (params) {
|
||||
return {
|
||||
q: params.term, // search term
|
||||
page: params.page
|
||||
};
|
||||
},
|
||||
processResults: function (data, params) {
|
||||
return {
|
||||
results : data.data.results
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
var uploader = WebUploader.create({
|
||||
auto: false,
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<!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>
|
||||
<meta name="keywords" content="MinDoc,文档在线管理系统,WIKI,wiki,wiki在线,文档在线管理,接口文档在线管理,接口文档管理">
|
||||
<meta name="description" content="MinDoc文档在线管理系统 {{.site_description}}">
|
||||
<meta name="author" content="Minho" />
|
||||
<meta name="site" content="https://www.iminho.me" />
|
||||
<!-- Bootstrap -->
|
||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
|
||||
|
||||
<link href="{{cdncss "/static/css/main.css" "version"}}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="manual-reader manual-container manual-search-reader">
|
||||
{{template "widgets/header.tpl" .}}
|
||||
<div class="container manual-body">
|
||||
<div class="search-head">
|
||||
<strong class="search-title">项目集列表</strong>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="hide tag-container-outer" style="border: 0;margin-top: 0;padding: 5px 15px;min-height: 200px;">
|
||||
<div class="attach-list" id="ItemsetsList">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="10%">#</th>
|
||||
<th width="30%">项目集名称</th>
|
||||
<th width="20%">项目集标识</th>
|
||||
<th width="10%">项目数量</th>
|
||||
<th width="15%">创建时间</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $index,$item := .Lists}}
|
||||
<tr>
|
||||
<td>{{$item.ItemId}}</td>
|
||||
<td>{{$item.ItemName}}</td>
|
||||
<td>{{$item.ItemKey}}</td>
|
||||
<td>{{$item.BookNumber}}</td>
|
||||
<td>{{$item.CreateTimeString}}</td>
|
||||
<td>
|
||||
<a href="{{urlfor "ItemsetsController.List" ":key" $item.ItemKey}}" class="btn btn-success btn-sm" target="_blank">详情</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr><td class="text-center" colspan="6">暂无数据</td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="pagination-container">
|
||||
{{if gt .TotalPages 1}}
|
||||
{{.PageHtml}}
|
||||
{{end}}
|
||||
<div class="clearfix"></div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
{{template "widgets/footer.tpl" .}}
|
||||
</div>
|
||||
<script src="{{cdnjs "/static/jquery/1.12.4/jquery.min.js"}}" type="text/javascript"></script>
|
||||
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}" type="text/javascript"></script>
|
||||
{{.Scripts}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,66 @@
|
|||
<!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>项目集{{.Model.ItemName}}的项目列表 - Powered by MinDoc</title>
|
||||
<meta name="keywords" content="MinDoc,文档在线管理系统,WIKI,wiki,wiki在线,文档在线管理,接口文档在线管理,接口文档管理,{{.Model.ItemName}}">
|
||||
<meta name="description" content="MinDoc文档在线管理系统 {{.site_description}}">
|
||||
<!-- Bootstrap -->
|
||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||
<link href="{{cdncss "/static/font-awesome/css/font-awesome.min.css"}}" rel="stylesheet">
|
||||
|
||||
<link href="{{cdncss "/static/css/main.css" "version"}}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="manual-reader manual-container manual-search-reader">
|
||||
{{template "widgets/header.tpl" .}}
|
||||
<div class="container manual-body">
|
||||
<div class="search-head">
|
||||
<strong class="search-title">显示项目集为"{{.Model.ItemName}}"的项目</strong>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="manual-list">
|
||||
{{range $index,$item := .Lists}}
|
||||
<div class="list-item">
|
||||
<dl class="manual-item-standard">
|
||||
<dt>
|
||||
<a href="{{urlfor "DocumentController.Index" ":key" $item.Identify}}" title="{{$item.BookName}}-{{$item.CreateName}}" target="_blank">
|
||||
<img src="{{cdnimg $item.Cover}}" class="cover" alt="{{$item.BookName}}-{{$item.CreateName}}">
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="{{urlfor "DocumentController.Index" ":key" $item.Identify}}" class="name" title="{{$item.BookName}}-{{$item.CreateName}}" target="_blank">{{$item.BookName}}</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<span class="author">
|
||||
<b class="text">作者</b>
|
||||
<b class="text">-</b>
|
||||
<b class="text">{{if eq $item.RealName "" }}{{$item.CreateName}}{{else}}{{$item.RealName}}{{end}}</b>
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="search-empty">
|
||||
<img src="{{cdnimg "/static/images/search_empty.png"}}" class="empty-image">
|
||||
<span class="empty-text">暂无项目</span>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<nav class="pagination-container">
|
||||
{{.PageHtml}}
|
||||
</nav>
|
||||
</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>
|
||||
{{.Scripts}}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,257 @@
|
|||
<!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" "version"}}" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="manual-reader">
|
||||
{{template "widgets/header.tpl" .}}
|
||||
<div class="container manual-body">
|
||||
<div class="row">
|
||||
{{template "manager/widgets.tpl" "itemsets"}}
|
||||
<div class="page-right">
|
||||
<div class="m-box">
|
||||
<div class="box-head">
|
||||
<strong class="box-title">项目集管理</strong>
|
||||
{{if eq .Member.Role 0}}
|
||||
<button type="button" class="btn btn-success btn-sm pull-right" data-toggle="modal" data-target="#addItemsetsDialogModal"><i class="fa fa-plus" aria-hidden="true"></i> 创建项目集</button>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="attach-list" id="ItemsetsList">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="10%">#</th>
|
||||
<th width="30%">项目集名称</th>
|
||||
<th width="20%">项目集标识</th>
|
||||
<th width="20%">项目数量</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range $index,$item := .Lists}}
|
||||
<tr>
|
||||
<td>{{$item.ItemId}}</td>
|
||||
<td>{{$item.ItemName}}</td>
|
||||
<td>{{$item.ItemKey}}</td>
|
||||
<td>{{$item.BookNumber}}</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-default" data-id="{{$item.ItemId}}" data-method="edit" data-name="{{$item.ItemName}}" data-key="{{$item.ItemKey}}">编辑</button>
|
||||
<button type="button" data-method="delete" class="btn btn-danger btn-sm" data-id="{{$item.ItemId}}" data-loading-text="删除中...">删除</button>
|
||||
<a href="{{urlfor "ItemsetsController.Index" ":key" $item.ItemKey}}" 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>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="addItemsetsDialogModal" tabindex="-1" role="dialog" aria-labelledby="addItemsetsDialogModalLabel">
|
||||
<div class="modal-dialog">
|
||||
<form method="post" autocomplete="off" class="form-horizontal" action="{{urlfor "ManagerController.ItemsetsEdit"}}" id="addItemsetsDialogForm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">创建项目集</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label" for="account">项目集名称<span class="error-message">*</span></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="itemName" class="form-control" placeholder="项目集名称" id="itemName" maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label" for="itemKey">项目集标识<span class="error-message">*</span></label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" name="itemKey" id="itemKey" class="form-control" placeholder="项目集标识" maxlength="50">
|
||||
<p class="text">项目集标识只能由字母和数字组成且在2-100字符之间</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span id="create-form-error-message"></span>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button type="submit" class="btn btn-success" data-loading-text="保存中..." id="btnAddItemsets">保存
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div><!--END Modal-->
|
||||
<div class="modal fade" id="editItemsetsDialogModal" tabindex="-1" role="dialog" aria-labelledby="editItemsetsDialogModalLabel">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form method="post" autocomplete="off" class="form-horizontal" action="{{urlfor "ManagerController.ItemsetsEdit"}}" id="editItemsetsDialogForm">
|
||||
<input type="hidden" name="itemId" value="">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">编辑项目集</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="itemName">项目集名称<span class="error-message">*</span></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" name="itemName" id="itemName" class="form-control" placeholder="项目集名称" maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label" for="itemKey">项目集标识<span class="error-message">*</span></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" name="itemKey" id="itemKey" class="form-control" placeholder="项目集标识" maxlength="50">
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<span id="edit-form-error-message"></span>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||
<button type="submit" class="btn btn-success" data-loading-text="保存中..." id="btnEditItemsets">保存
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div><!--END Modal-->
|
||||
<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 src="{{cdnjs "/static/js/main.js"}}" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var editItemsetsDialogModal = $("#editItemsetsDialogModal");
|
||||
var addItemsetsDialogForm = $("#addItemsetsDialogForm");
|
||||
var editItemsetsDialogForm = $("#editItemsetsDialogForm");
|
||||
|
||||
editItemsetsDialogModal.on("shown.bs.modal",function () {
|
||||
editItemsetsDialogModal.find("input[name='itemName']").focus();
|
||||
});
|
||||
$("#addItemsetsDialogModal").on("show.bs.modal", function () {
|
||||
window.addItemsetsDialogModalHtml = $(this).find("form").html();
|
||||
}).on("hidden.bs.modal", function () {
|
||||
$(this).find("form").html(window.addItemsetsDialogModalHtml);
|
||||
});
|
||||
|
||||
addItemsetsDialogForm.ajaxForm({
|
||||
beforeSubmit: function () {
|
||||
var $itemName = addItemsetsDialogForm.find("input[name='itemName']").val();
|
||||
var $itemKey = addItemsetsDialogForm.find("input[name='itemKey']").val();
|
||||
|
||||
if ($itemName == "") {
|
||||
showError("项目集名称不能为空","#create-form-error-message");
|
||||
}
|
||||
if ($itemKey == "") {
|
||||
showError("项目集标识不能为空","#create-form-error-message");
|
||||
}
|
||||
$("#btnAddItemsets").button("loading");
|
||||
showError("","#create-form-error-message");
|
||||
return true;
|
||||
},
|
||||
success: function ($res) {
|
||||
if ($res.errcode === 0) {
|
||||
window.location = window.document.location;
|
||||
} else {
|
||||
showError($res.message,"#create-form-error-message");
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
showError("服务器异常","#create-form-error-message");
|
||||
},
|
||||
complete: function () {
|
||||
$("#btnAddItemsets").button("reset");
|
||||
}
|
||||
});
|
||||
|
||||
editItemsetsDialogForm.ajaxForm({
|
||||
beforeSubmit: function () {
|
||||
var $itemName = editItemsetsDialogForm.find("input[name='itemName']").val();
|
||||
var $itemKey = editItemsetsDialogForm.find("input[name='itemKey']").val();
|
||||
|
||||
if ($itemName == "") {
|
||||
showError("项目集名称不能为空","#edit-form-error-message");
|
||||
}
|
||||
if ($itemKey == "") {
|
||||
showError("项目集标识不能为空","#edit-form-error-message");
|
||||
}
|
||||
$("#btnEditItemsets").button("loading");
|
||||
showError("","#edit-form-error-message");
|
||||
return true;
|
||||
} ,
|
||||
success : function ($res) {
|
||||
if ($res.errcode === 0) {
|
||||
window.location = window.document.location;
|
||||
} else {
|
||||
showError($res.message,"#edit-form-error-message");
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
showError("服务器异常","#edit-form-error-message");
|
||||
},
|
||||
complete: function () {
|
||||
$("#btnEditItemsets").button("reset");
|
||||
}
|
||||
});
|
||||
|
||||
$("#ItemsetsList").on("click","button[data-method='delete']",function () {
|
||||
var id = $(this).attr("data-id");
|
||||
var $this = $(this);
|
||||
$(this).button("loading");
|
||||
$.ajax({
|
||||
url : "{{urlfor "ManagerController.ItemsetsDelete" ":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");
|
||||
}
|
||||
});
|
||||
}).on("click","button[data-method='edit']",function () {
|
||||
var $itemId = $(this).attr("data-id");
|
||||
var $itemName = $(this).attr("data-name");
|
||||
var $itemKey = $(this).attr("data-key");
|
||||
|
||||
editItemsetsDialogModal.find("input[name='itemId']").val($itemId);
|
||||
editItemsetsDialogModal.find("input[name='itemName']").val($itemName);
|
||||
editItemsetsDialogModal.find("input[name='itemKey']").val($itemKey);
|
||||
|
||||
editItemsetsDialogModal.modal("show");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -4,6 +4,8 @@
|
|||
<li{{if eq "users" .}} class="active"{{end}}><a href="{{urlfor "ManagerController.Users" }}" class="item"><i class="fa fa-user" aria-hidden="true"></i> 用户管理</a> </li>
|
||||
<li{{if eq "team" .}} class="active"{{end}}><a href="{{urlfor "ManagerController.Team" }}" class="item"><i class="fa fa-group" aria-hidden="true"></i> 团队管理</a> </li>
|
||||
<li{{if eq "books" .}} class="active"{{end}}><a href="{{urlfor "ManagerController.Books" }}" class="item"><i class="fa fa-book" aria-hidden="true"></i> 项目管理</a> </li>
|
||||
<li{{if eq "itemsets" .}} class="active"{{end}}><a href="{{urlfor "ManagerController.Itemsets" }}" class="item"><i class="fa fa-archive" 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{{if eq "setting" .}} class="active"{{end}}><a href="{{urlfor "ManagerController.Setting" }}" class="item"><i class="fa fa-cogs" aria-hidden="true"></i> 配置管理</a> </li>
|
||||
{{/*<li{{if eq "config" .}} class="active"{{end}}><a href="{{urlfor "ManagerController.Config" }}" class="item"><i class="fa fa-file" aria-hidden="true"></i> 配置文件</a> </li>*/}}
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<li {{if eq .ControllerName "BlogController"}}{{if eq .ActionName "List" "Index"}}class="active"{{end}}{{end}}>
|
||||
<a href="{{urlfor "BlogController.List" }}" title="文章">文章</a>
|
||||
</li>
|
||||
<li {{if eq .ControllerName "LabelController"}}class="active"{{end}}>
|
||||
<a href="{{urlfor "LabelController.List" }}" title="标签">标签</a>
|
||||
<li {{if eq .ControllerName "ItemsetsController"}}class="active"{{end}}>
|
||||
<a href="{{urlfor "ItemsetsController.Index" }}" title="项目集">项目集</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="searchbar pull-left visible-lg-inline-block visible-md-inline-block">
|
||||
|
|
Loading…
Reference in New Issue