diff --git a/conf/app.conf b/conf/app.conf
index dc79ee37..7c1ff29e 100644
--- a/conf/app.conf
+++ b/conf/app.conf
@@ -18,4 +18,5 @@ db_database=mindoc_db
db_username=root
db_password=123456
-queue_size=50
\ No newline at end of file
+#项目默认封面
+cover=/static/images/book.jpg
\ No newline at end of file
diff --git a/controllers/book.go b/controllers/book.go
index d56657f6..56fadb46 100644
--- a/controllers/book.go
+++ b/controllers/book.go
@@ -1,38 +1,228 @@
package controllers
-import "strings"
+import (
+ "strings"
+ "regexp"
+ "strconv"
+ "time"
+ "encoding/json"
+ "html/template"
+
+ "github.com/lifei6671/godoc/models"
+ "github.com/lifei6671/godoc/utils"
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/orm"
+)
type BookController struct {
BaseController
}
-func (p *BookController) Index() {
- p.TplName = "book/index.tpl"
+func (c *BookController) Index() {
+ c.Prepare()
+ c.TplName = "book/index.tpl"
+
+ pageIndex, _ := c.GetInt("page", 1)
+
+ books,totalCount,err := models.NewBook().FindToPager(pageIndex,10,c.Member.MemberId)
+
+ if err != nil {
+ c.Abort("500")
+ }
+
+ html := utils.GetPagerHtml(c.Ctx.Request.RequestURI,pageIndex,10,totalCount)
+
+ c.Data["PageHtml"] = html
+
+ b,err := json.Marshal(books)
+
+ if err != nil {
+ c.Data["Result"] = template.JS("[]")
+ }else{
+ c.Data["Result"] = template.JS(string(b))
+ }
}
// Dashboard 项目概要 .
-func (p *BookController) Dashboard() {
- p.TplName = "book/dashboard.tpl"
+func (c *BookController) Dashboard() {
+ c.Prepare()
+ c.TplName = "book/dashboard.tpl"
+
+ key := c.Ctx.Input.Param(":key")
+
+ if key == ""{
+ c.Abort("404")
+ }
+
+ book,err := models.NewBookResult().FindByIdentify(key,c.Member.MemberId)
+ if err != nil {
+ if err == models.ErrPermissionDenied {
+ c.Abort("403")
+ }
+ c.Abort("500")
+ }
+
+ c.Data["Model"] = *book
}
// Setting 项目设置 .
-func (p *BookController) Setting() {
- p.TplName = "book/setting.tpl"
+func (c *BookController) Setting() {
+ c.Prepare()
+ c.TplName = "book/setting.tpl"
+
+ key := c.Ctx.Input.Param(":key")
+
+ if key == ""{
+ c.Abort("404")
+ }
+
+ book,err := models.NewBookResult().FindByIdentify(key,c.Member.MemberId)
+ if err != nil {
+ if err == models.ErrPermissionDenied {
+ c.Abort("403")
+ }
+ c.Abort("500")
+ }
+
+ c.Data["Model"] = *book
+
+}
+//用户列表.
+func (c *BookController) Users() {
+ c.Prepare()
+ c.TplName = "book/users.tpl"
+
+ key := c.Ctx.Input.Param(":key")
+ pageIndex,_ := c.GetInt("page",1)
+
+ if key == ""{
+ c.Abort("404")
+ }
+
+ book,err := models.NewBookResult().FindByIdentify(key,c.Member.MemberId)
+ if err != nil {
+ if err == models.ErrPermissionDenied {
+ c.Abort("403")
+ }
+ c.Abort("500")
+ }
+
+ c.Data["Model"] = *book
+
+ members,totalCount,err := models.NewMemberRelationshipResult().FindForUsersByBookId(book.BookId,pageIndex,15)
+
+ html := utils.GetPagerHtml(c.Ctx.Request.RequestURI,pageIndex,10,totalCount)
+
+ c.Data["PageHtml"] = html
+ b,err := json.Marshal(members)
+
+ if err != nil {
+ c.Data["Result"] = template.JS("[]")
+ }else{
+ c.Data["Result"] = template.JS(string(b))
+ }
}
-func (p *BookController) Users() {
- p.TplName = "book/users.tpl"
+func (c *BookController) AddMember() {
+ identify := c.GetString("identify")
+ account := c.GetString("account")
+ role_id,_ := c.GetInt("role_id",3)
+
+ if identify == "" || account == ""{
+ c.JsonResult(6001,"参数错误")
+ }
+ book ,err := models.NewBookResult().FindByIdentify("identify",c.Member.MemberId)
+
+ if err != nil {
+ if err == models.ErrPermissionDenied {
+ c.JsonResult(403,"权限不足")
+ }
+ if err == orm.ErrNoRows {
+ c.JsonResult(404,"项目不能存在")
+ }
+ c.JsonResult(6002,err.Error())
+ }
+ if book.RoleId != 0 && book.RoleId != 1 {
+ c.JsonResult(403,"权限不足")
+ }
+
+ member := models.NewMember()
+
+ if err := member.FindByAccount(account) ; err != nil {
+ c.JsonResult(404,"用户不存在")
+ }
+
+ if _,err := models.NewRelationship().FindForRoleId(book.BookId,member.MemberId);err == orm.ErrNoRows {
+ c.JsonResult(6003,"用户已存在该项目中")
+ }
+
+ relationship := models.NewRelationship()
+ relationship.BookId = book.BookId
+ relationship.MemberId = member.MemberId
+ relationship.RoleId = role_id
+
+ if err := relationship.Insert(); err == nil {
+ c.JsonResult(0,"ok",member)
+ }
+ c.JsonResult(500,err.Error())
}
+
func (c *BookController) Create() {
if c.Ctx.Input.IsPost() {
book_name := strings.TrimSpace(c.GetString("book_name",""))
identify := strings.TrimSpace(c.GetString("identify",""))
description := strings.TrimSpace(c.GetString("description",""))
- privately_owned := c.GetString("privately_owned")
+ privately_owned,_ := strconv.Atoi(c.GetString("privately_owned"))
comment_status := c.GetString("comment_status")
+ if book_name == "" {
+ c.JsonResult(6001,"项目名称不能为空")
+ }
+ if identify == "" {
+ c.JsonResult(6002,"项目标识不能为空")
+ }
+ if ok,err := regexp.MatchString(`^[a-z]+[a-zA-Z0-9_\-]*$`,identify); !ok || err != nil {
+ c.JsonResult(6003,"文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头")
+ }
+ if strings.Count(identify,"") > 50 {
+ c.JsonResult(6004,"文档标识不能超过50字")
+ }
+ if strings.Count(description,"") > 500 {
+ c.JsonResult(6004,"项目描述不能大于500字")
+ }
+ if privately_owned !=0 && privately_owned != 1 {
+ privately_owned = 1
+ }
+ if comment_status != "open" && comment_status != "closed" && comment_status != "group_only" && comment_status != "registered_only" {
+ comment_status = "closed"
+ }
+
+ book := models.NewBook()
+
+ if books,err := book.FindByField("identify",identify); err == nil || len(books) > 0 {
+ c.JsonResult(6006,"项目标识已存在")
+ }
+
+ book.BookName = book_name
+ book.Description = description
+ book.CommentCount = 0
+ book.PrivatelyOwned = privately_owned
+ book.CommentStatus = comment_status
+ book.Identify = identify
+ book.DocCount = 0
+ book.MemberId = c.Member.MemberId
+ book.CommentCount = 0
+ book.Version = time.Now().Unix()
+ book.Cover = beego.AppConfig.String("cover")
+
+ err := book.Insert()
+
+ if err != nil {
+ c.JsonResult(6005,err.Error())
+ }
+ c.JsonResult(0,"ok",book)
}
c.JsonResult(6001,"error")
}
diff --git a/models/base.go b/models/base.go
new file mode 100644
index 00000000..081606ff
--- /dev/null
+++ b/models/base.go
@@ -0,0 +1,20 @@
+package models
+
+import "github.com/astaxie/beego/orm"
+
+type Model struct {
+
+}
+
+func (m *Model) Find(id int) error {
+ o := orm.NewOrm()
+
+ return o.Read(m)
+}
+
+func (m *Model) Insert() error {
+ o := orm.NewOrm()
+ _,err := o.Insert(m)
+
+ return err
+}
\ No newline at end of file
diff --git a/models/book.go b/models/book.go
index d2af9926..36638e88 100644
--- a/models/book.go
+++ b/models/book.go
@@ -1,6 +1,11 @@
package models
-import "time"
+import (
+ "time"
+
+ "github.com/astaxie/beego/orm"
+ "github.com/lifei6671/godoc/conf"
+)
// Book struct .
type Book struct {
@@ -9,17 +14,20 @@ type Book struct {
BookName string `orm:"column(book_name);size(500)" json:"book_name"`
// Identify 项目唯一标识.
Identify string `orm:"column(identify);size(100);unique" json:"identify"`
+ OrderIndex int `orm:"column(order_index);type(int);default(0)" json:"order_index"`
// Description 项目描述.
Description string `orm:"column(description);size(2000)" json:"description"`
+ Label string `orm:"column(label);size(500)" json:"label"`
// PrivatelyOwned 项目私有: 0 公开/ 1 私有
PrivatelyOwned int `orm:"column(privately_owned);type(int);default(0)" json:"privately_owned"`
// 当项目是私有时的访问Token.
- PrivateToken string `orm:"column(private_token);size(500)" json:"private_token"`
+ PrivateToken string `orm:"column(private_token);size(500);null" json:"private_token"`
// DocCount 包含文档数量.
DocCount int `orm:"column(doc_count);type(int)" json:"doc_count"`
- // CommentStatus 评论设置的状态:open为允许所有人评论,closed为不允许评论, group_only 仅允许参与者评论 ,registered_only 仅允许注册者评论.
+ // CommentStatus 评论设置的状态:open 为允许所有人评论,closed 为不允许评论, group_only 仅允许参与者评论 ,registered_only 仅允许注册者评论.
CommentStatus string `orm:"column(comment_status);size(20);default(open)" json:"comment_status"`
CommentCount int `orm:"column(comment_count);type(int)" json:"comment_count"`
+ Cover string `orm:"column();size(1000)" json:"cover"`
// CreateTime 创建时间 .
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add"`
@@ -28,6 +36,7 @@ type Book struct {
Version int64 `orm:"type(bigint);column(version)" json:"version"`
}
+
// TableName 获取对应数据库表名.
func (m *Book) TableName() string {
return "books"
@@ -36,4 +45,96 @@ func (m *Book) TableName() string {
func (m *Book) TableEngine() string {
return "INNODB"
}
+func (m *Book) TableNameWithPrefix() string {
+ return conf.GetDatabasePrefix() + m.TableName()
+}
+func NewBook() *Book {
+ return &Book{}
+}
+
+func (m *Book) Insert() error {
+ o := orm.NewOrm()
+ _,err := o.Insert(m)
+
+ return err
+}
+
+func (m *Book) Update(cols... string) error {
+ o := orm.NewOrm()
+
+ _,err := o.Update(m,cols...)
+ return err
+}
+
+func (m *Book) FindByField(field string,value interface{}) ([]Book,error) {
+ o := orm.NewOrm()
+
+ var books []Book
+ _,err := o.QueryTable(conf.GetDatabasePrefix() + m.TableName()).Filter(field,value).All(&books)
+
+ return books,err
+}
+
+func (m *Book) FindToPager(pageIndex, pageSize ,memberId int) (books []BookResult,totalCount int,err error){
+
+ relationship := NewRelationship()
+
+ o := orm.NewOrm()
+
+ qb, _ := orm.NewQueryBuilder("mysql")
+
+ qb.Select("COUNT(book.book_id) AS total_count").
+ From(m.TableNameWithPrefix() + " AS book").
+ LeftJoin(relationship.TableNameWithPrefix() + " AS rel").
+ On("book.book_id=rel.book_id").
+ Where("rel.member_id=?")
+
+ err = o.Raw(qb.String(),memberId).QueryRow(&totalCount)
+
+ if err != nil {
+ return
+ }
+
+ offset := (pageIndex - 1) * pageSize
+ qb2,_ := orm.NewQueryBuilder("mysql")
+
+ qb2.Select("book.*,rel.member_id","rel.role_id","m.account as create_name").
+ From(m.TableNameWithPrefix() + " AS book").
+ LeftJoin(relationship.TableNameWithPrefix() + " AS rel").
+ On("book.book_id=rel.book_id").
+ LeftJoin(NewMember().TableNameWithPrefix() + " AS m").On("rel.member_id=m.member_id AND rel.role_id=0").
+ Where("rel.member_id=?").
+ OrderBy("book.order_index").Desc().
+ Limit(pageSize).
+ Offset(offset)
+
+ _,err = o.Raw(qb2.String(),memberId).QueryRows(&books)
+
+ sql := "SELECT m.account,doc.modify_time FROM md_documents AS doc LEFT JOIN md_members AS m ON doc.modify_at=m.member_id WHERE book_id = ? LIMIT 1 ORDER BY doc.modify_time DESC"
+
+ if err == nil && len(books) > 0{
+ for index,book := range books {
+ var text struct{
+ Account string
+ ModifyTime time.Time
+ }
+
+
+ err1 := o.Raw(sql,book.BookId).QueryRow(&text)
+ if err1 == nil {
+ books[index].LastModifyText = text.Account + " 于 " + text.ModifyTime.Format("2006-01-02 15:04:05")
+ }
+ if book.RoleId == 0{
+ book.RoleName = "创始人"
+ }else if book.RoleId == 1 {
+ book.RoleName = "管理员"
+ }else if book.RoleId == 2 {
+ book.RoleName = "编辑者"
+ }else if book.RoleId == 2 {
+ book.RoleName = "观察者"
+ }
+ }
+ }
+ return
+}
\ No newline at end of file
diff --git a/models/book_result.go b/models/book_result.go
new file mode 100644
index 00000000..e7a9f82d
--- /dev/null
+++ b/models/book_result.go
@@ -0,0 +1,112 @@
+package models
+
+import (
+ "time"
+ "github.com/astaxie/beego/orm"
+ "strings"
+)
+
+type BookResult struct {
+ BookId int `json:"book_id"`
+ BookName string `json:"book_name"`
+ Identify string `json:"identify"`
+ OrderIndex int `json:"order_index"`
+ Description string `json:"description"`
+ PrivatelyOwned int `json:"privately_owned"`
+ PrivateToken string `json:"private_token"`
+ DocCount int `json:"doc_count"`
+ CommentStatus string `json:"comment_status"`
+ CommentCount int `json:"comment_count"`
+ CreateTime time.Time `json:"create_time"`
+ CreateName string `json:"create_name"`
+ ModifyTime time.Time `json:"modify_time"`
+ Cover string `json:"cover"`
+ Label string `json:"label"`
+ MemberId int `json:"member_id"`
+ RoleId int `json:"role_id"`
+ RoleName string `json:"role_name"`
+
+ LastModifyText string `json:"last_modify_text"`
+}
+
+func NewBookResult() *BookResult {
+ return &BookResult{}
+}
+
+func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,error) {
+ o := orm.NewOrm()
+
+ book := NewBook()
+
+ err := o.QueryTable(book.TableNameWithPrefix()).Filter("identify", identify).One(book)
+
+ if err != nil {
+ return m, err
+ }
+
+ relationship := NewRelationship()
+
+ err = o.QueryTable(relationship.TableNameWithPrefix()).Filter("book_id",book.BookId).Filter("member_id",member_id).One(relationship)
+
+ if err != nil {
+ return m,err
+ }
+ var relationship2 Relationship
+
+ err = o.QueryTable(relationship.TableNameWithPrefix()).Filter("book_id",book.BookId).Filter("role_id",0).One(&relationship2)
+
+ if err != nil {
+ return m,ErrPermissionDenied
+ }
+
+ member := NewMember()
+
+ err = member.Find(relationship2.MemberId)
+ if err != nil {
+ return m,err
+ }
+
+ m.BookId = book.BookId
+ m.BookName = book.BookName
+ m.Identify = book.Identify
+ m.OrderIndex = book.OrderIndex
+ m.Description = strings.Replace(book.Description,"\r\n","
",-1)
+ m.PrivatelyOwned = book.PrivatelyOwned
+ m.PrivateToken = book.PrivateToken
+ m.DocCount = book.DocCount
+ m.CommentStatus = book.CommentStatus
+ m.CommentCount = book.CommentCount
+ m.CreateTime = book.CreateTime
+ m.CreateName = member.Account
+ m.ModifyTime = book.ModifyTime
+ m.Cover = book.Cover
+ m.Label = book.Label
+
+ m.MemberId = relationship.MemberId
+ m.RoleId = relationship.RoleId
+
+ if m.RoleId == 0{
+ m.RoleName = "创始人"
+ }else if m.RoleId == 1 {
+ m.RoleName = "管理员"
+ }else if m.RoleId == 2 {
+ m.RoleName = "编辑者"
+ }else if m.RoleId == 2 {
+ m.RoleName = "观察者"
+ }
+
+
+ doc := NewDocument()
+
+ err = o.QueryTable(doc.TableNameWithPrefix()).Filter("book_id",book.BookId).OrderBy("modify_time").One(doc)
+
+ if err == nil {
+ member2 := NewMember()
+ member2.Find(doc.ModifyAt)
+
+ m.LastModifyText = member2.Account + " 于 " + doc.ModifyTime.Format("2006-01-02 15:04:05")
+ }
+
+ return m,nil
+
+}
diff --git a/models/document.go b/models/document.go
index 5cafaaba..f358be4b 100644
--- a/models/document.go
+++ b/models/document.go
@@ -1,6 +1,9 @@
package models
-import "time"
+import (
+ "time"
+ "github.com/lifei6671/godoc/conf"
+)
// Document struct.
type Document struct {
@@ -32,3 +35,30 @@ func (m *Document) TableName() string {
func (m *Document) TableEngine() string {
return "INNODB"
}
+
+func (m *Document) TableNameWithPrefix() string {
+ return conf.GetDatabasePrefix() + m.TableName()
+}
+
+func NewDocument() *Document {
+ return &Document{}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/models/errors.go b/models/errors.go
index 41038acf..8cbcf3d9 100644
--- a/models/errors.go
+++ b/models/errors.go
@@ -13,4 +13,6 @@ var(
// ErrInvalidParameter 参数错误.
ErrInvalidParameter = errors.New("Invalid parameter")
+
+ ErrPermissionDenied = errors.New("Permission denied")
)
diff --git a/models/member.go b/models/member.go
index a03960e7..7b0ca226 100644
--- a/models/member.go
+++ b/models/member.go
@@ -5,6 +5,7 @@ import (
"time"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/godoc/utils"
+ "github.com/lifei6671/godoc/conf"
)
type Member struct {
@@ -31,6 +32,10 @@ func (m *Member) TableEngine() string {
return "INNODB"
}
+func (m *Member)TableNameWithPrefix() string {
+ return conf.GetDatabasePrefix() + m.TableName()
+}
+
func NewMember() *Member {
return &Member{}
}
@@ -94,4 +99,33 @@ func (m *Member) Find(id int) error{
return err
}
return nil
-}
\ No newline at end of file
+}
+
+func (m *Member) FindByAccount (account string) error {
+ o := orm.NewOrm()
+
+ err := o.QueryTable(m.TableNameWithPrefix()).Filter("account",account).One(m)
+
+ return err
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/models/member_result.go b/models/member_result.go
new file mode 100644
index 00000000..6291a875
--- /dev/null
+++ b/models/member_result.go
@@ -0,0 +1,60 @@
+package models
+
+import (
+ "time"
+ "github.com/astaxie/beego/orm"
+)
+
+type MemberRelationshipResult struct {
+ MemberId int `json:"member_id"`
+ Account string `json:"account"`
+ Description string `json:"description"`
+ Email string `json:"email"`
+ Phone string `json:"phone"`
+ Avatar string `json:"avatar"`
+ Role int `json:"role"` //用户角色:0 管理员/ 1 普通用户
+ Status int `json:"status"` //用户状态:0 正常/1 禁用
+ CreateTime time.Time `json:"create_time"`
+ CreateAt int `json:"create_at"`
+ RelationshipId int `json:"relationship_id"`
+ BookId int `json:"book_id"`
+ // RoleId 角色:0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者
+ RoleId int `json:"role_id"`
+}
+
+func NewMemberRelationshipResult() *MemberRelationshipResult {
+ return &MemberRelationshipResult{}
+}
+
+func (m *MemberRelationshipResult) FindForUsersByBookId(book_id ,pageIndex, pageSize int) ([]MemberRelationshipResult,int,error) {
+ o := orm.NewOrm()
+
+ var members []MemberRelationshipResult
+
+ sql1 := "SELECT * FROM md_relationship AS rel LEFT JOIN md_members as member ON rel.member_id = member.member_id WHERE rel.book_id = ? ORDER BY rel.relationship_id DESC LIMIT ?,?"
+
+ sql2 := "SELECT count(*) AS total_count FROM md_relationship AS rel LEFT JOIN md_members as member ON rel.member_id = member.member_id WHERE rel.book_id = ?"
+
+ var total_count int
+
+ err := o.Raw(sql2,book_id).QueryRow(&total_count)
+
+ if err != nil {
+ return members,0,err
+ }
+
+ offset := (pageIndex-1) * pageSize
+
+ _,err = o.Raw(sql1,book_id,offset,pageSize).QueryRows(&members)
+
+ if err != nil {
+ return members,0,err
+ }
+
+ return members,total_count,nil
+}
+
+
+
+
+
diff --git a/models/relationship.go b/models/relationship.go
index 394fddc8..c483e037 100644
--- a/models/relationship.go
+++ b/models/relationship.go
@@ -1,5 +1,10 @@
package models
+import (
+ "github.com/lifei6671/godoc/conf"
+ "github.com/astaxie/beego/orm"
+)
+
type Relationship struct {
RelationshipId int `orm:"pk;auto;unique;column(relationship_id)" json:"relationship_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
@@ -13,6 +18,10 @@ type Relationship struct {
func (m *Relationship) TableName() string {
return "relationship"
}
+func (m *Relationship) TableNameWithPrefix() string {
+ return conf.GetDatabasePrefix() + m.TableName()
+}
+
// TableEngine 获取数据使用的引擎.
func (m *Relationship) TableEngine() string {
return "INNODB"
@@ -23,4 +32,40 @@ func (u *Relationship) TableUnique() [][]string {
return [][]string{
[]string{"MemberId", "BookId"},
}
-}
\ No newline at end of file
+}
+
+func NewRelationship() *Relationship {
+ return &Relationship{}
+}
+
+func (m *Relationship) FindForRoleId(book_id ,member_id int) (int,error) {
+ o := orm.NewOrm()
+
+ relationship := NewRelationship()
+
+ err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",member_id).One(relationship)
+
+ if err != nil {
+ return 0,err
+ }
+ return relationship.RoleId,nil
+}
+
+func (m *Relationship) Insert() error {
+ o := orm.NewOrm()
+
+ _,err := o.Insert(m)
+
+ return err
+}
+
+func (m *Relationship) Update() error {
+ o := orm.NewOrm()
+
+ _,err := o.Update(m)
+
+ return err
+}
+
+
+
diff --git a/routers/router.go b/routers/router.go
index d6a2640d..c5d73646 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -24,8 +24,9 @@ func init() {
beego.Router("/book/:key/dashboard", &controllers.BookController{},"*:Dashboard")
beego.Router("/book/:key/setting", &controllers.BookController{},"*:Setting")
beego.Router("/book/:key/users", &controllers.BookController{},"*:Users")
- beego.Router("/book/:key/edit/:id", &controllers.BookController{},"*:Edit")
+ beego.Router("/book/:key/edit", &controllers.BookController{},"*:Edit")
beego.Router("/book/create", &controllers.BookController{},"*:Create")
+ beego.Router("/book/member/create", &controllers.BookController{},"POST:AddMember")
beego.Router("/book/:key/users/create", &controllers.BookMemberController{},"*:Create")
beego.Router("/book/:key/users/change", &controllers.BookMemberController{},"*:Change")
diff --git a/static/js/main.js b/static/js/main.js
index f1aa93f4..a98557cf 100644
--- a/static/js/main.js
+++ b/static/js/main.js
@@ -10,4 +10,25 @@ function showError($msg) {
function showSuccess($msg) {
$("#form-error-message").addClass("success-message").removeClass("error-message").text($msg);
return true;
-}
\ No newline at end of file
+}
+
+Date.prototype.format = function(fmt) {
+ var o = {
+ "M+" : this.getMonth()+1, //月份
+ "d+" : this.getDate(), //日
+ "h+" : this.getHours(), //小时
+ "m+" : this.getMinutes(), //分
+ "s+" : this.getSeconds(), //秒
+ "q+" : Math.floor((this.getMonth()+3)/3), //季度
+ "S" : this.getMilliseconds() //毫秒
+ };
+ if(/(y+)/.test(fmt)) {
+ fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
+ }
+ for(var k in o) {
+ if(new RegExp("("+ k +")").test(fmt)){
+ fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
+ }
+ }
+ return fmt;
+};
\ No newline at end of file
diff --git a/utils/pager.go b/utils/pager.go
new file mode 100644
index 00000000..74c3b30e
--- /dev/null
+++ b/utils/pager.go
@@ -0,0 +1,332 @@
+package utils
+
+import (
+ // "fmt"
+ html "html/template"
+ con "strconv"
+ "strings"
+
+ "github.com/astaxie/beego/orm"
+ "fmt"
+)
+
+type PageOptions struct {
+ TableName string //表名 -----------------[必填]
+ Conditions string //条件
+ CurrentPage int //当前页 ,默认1 每次分页,必须在前台设置新的页数,不设置始终默认1.在控制器中使用方式:cp, _ := this.GetInt("pno") po.CurrentPage = int(cp)
+ PageSize int //页面大小,默认20
+ LinkItemCount int //生成A标签的个数 默认10个
+ Href string //A标签的链接地址 ---------[不需要设置]
+ ParamName string //参数名称 默认是pno
+ FirstPageText string //首页文字 默认"首页"
+ LastPageText string //尾页文字 默认"尾页"
+ PrePageText string //上一页文字 默认"上一页"
+ NextPageText string //下一页文字 默认"下一页"
+ EnableFirstLastLink bool //是否启用首尾连接 默认false 建议开启
+ EnablePreNexLink bool //是否启用上一页,下一页连接 默认false 建议开启
+}
+
+/**
+ * 分页函数,适用任何表
+ * 返回 总记录条数,总页数,以及当前请求的数据RawSeter,调用中需要"rs.QueryRows(&tblog)"就行了 --tblog是一个Tb_log对象
+ * 参数:表名,当前页数,页面大小,条件(查询条件,格式为 " and name='zhifeiya' and age=12 ")
+ */
+func GetPagesInfo(tableName string, currentpage int, pagesize int, conditions string) (int, int, orm.RawSeter) {
+ if currentpage <= 1 {
+ currentpage = 1
+ }
+ if pagesize == 0 {
+ pagesize = 20
+ }
+ var rs orm.RawSeter
+ o := orm.NewOrm()
+ var totalItem, totalpages int = 0, 0 //总条数,总页数
+ o.Raw("SELECT count(*) FROM " + tableName + " where 1 > 0 " + conditions).QueryRow(&totalItem) //获取总条数
+ if totalItem <= pagesize {
+ totalpages = 1
+ } else if totalItem > pagesize {
+ temp := totalItem / pagesize
+ if (totalItem % pagesize) != 0 {
+ temp = temp + 1
+ }
+ totalpages = temp
+ }
+ rs = o.Raw("select * from " + tableName + " where 1 > 0 " + conditions + " LIMIT " + con.Itoa((currentpage-1)*pagesize) + "," + con.Itoa(pagesize))
+ return totalItem, totalpages, rs
+}
+
+/**
+ * 返回总记录条数,总页数,当前页面数据,分页html
+ * 根据分页选项,生成分页连接 下面是一个实例:
+ func (this *MainController) Test() {
+ var po util.PageOptions
+ po.EnablePreNexLink = true
+ po.EnableFirstLastLink = true
+ po.LinkItemCount = 7
+ po.TableName = "help_topic"
+ cp, _ := this.GetInt("pno")
+ po.CurrentPage = int(cp)
+ _,_,_ pager := util.GetPagerLinks(&po, this.Ctx)
+ this.Data["Email"] = html.HTML(pager)
+ this.TplName = "test.html"
+ }
+*/
+func GetPagerLinks(po *PageOptions,requestURI string) (int, int, orm.RawSeter, html.HTML) {
+ str := ""
+ totalItem, totalpages, rs := GetPagesInfo(po.TableName, po.CurrentPage, po.PageSize, po.Conditions)
+ po = setDefault(po, totalpages)
+ DealUri(po, requestURI)
+ if totalpages <= po.LinkItemCount {
+ str = fun1(po, totalpages) //显示完全 12345678910
+ } else if totalpages > po.LinkItemCount {
+ if po.CurrentPage < po.LinkItemCount {
+ str = fun2(po, totalpages) //123456789...200
+ } else {
+ if po.CurrentPage + po.LinkItemCount < totalpages {
+ str = fun3(po, totalpages)
+ } else {
+ str = fun4(po, totalpages)
+ }
+ }
+ }
+ return totalItem, totalpages, rs, html.HTML(str)
+}
+
+func GetPagerHtml(requestURI string,pageIndex, pageSize,totalCount int) (html.HTML){
+ po := &PageOptions{
+ CurrentPage: pageIndex,
+ PageSize: pageSize,
+ EnableFirstLastLink : true,
+ ParamName : "page",
+ }
+ setDefault(po,totalCount)
+ DealUri(po,requestURI)
+ str := ""
+ if totalCount <= po.LinkItemCount {
+ str = fun1(po, totalCount) //显示完全 12345678910
+ } else if totalCount > po.LinkItemCount {
+ if po.CurrentPage < po.LinkItemCount {
+ str = fun2(po, totalCount) //123456789...200
+ } else {
+ if po.CurrentPage + po.LinkItemCount < totalCount {
+ str = fun3(po, totalCount)
+ } else {
+ str = fun4(po, totalCount)
+ }
+ }
+ }
+ str = strings.Replace(str,"?&","?",-1)
+ //str = strings.Replace(str,"&&","&",-1)
+ return html.HTML(str)
+}
+
+/**
+ * 处理url,目的是保存参数
+ */
+func DealUri(po *PageOptions, requestURI string) {
+ var rs string
+ if strings.Contains(requestURI, "?") {
+ arr := strings.Split(requestURI, "?")
+ rs = ""
+ arr2 := strings.Split(arr[1], "&")
+ for _, v := range arr2 {
+ if !strings.Contains(v, po.ParamName) {
+ if strings.HasSuffix(rs,"&") {
+ rs += v
+ }else{
+ rs += v + "&"
+ }
+ //rs += "&" + v
+ }
+ }
+ if strings.HasPrefix(rs,"&") {
+ rs = string(rs[1:])
+ }
+ if strings.HasSuffix(rs,"&"){
+ rs = string(rs[0:strings.Count(rs,"")-1])
+ }
+ rs = arr[0] + "?" + rs
+ fmt.Println(rs)
+ } else {
+ //rs = requestURI + "?" //+ po.ParamName + "time=" + con.Itoa(time.Now().Second())
+ rs = requestURI + "?"
+ }
+
+ po.Href = rs
+}
+
+/**
+ * 1...197 198 199 200
+ */
+func fun4(po *PageOptions, totalPages int) string {
+ rs := ""
+ rs += getHeader(po, totalPages)
+ rs += "
文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母打头
+文档标识只能包含小写字母、数字,以及“-”和“_”符号,并且只能小写字母开头