Browse Source

1、实现删除项目
2、实现生成访问令牌
3、实现添加评论

lifei6671 8 years ago
parent
commit
d1b2c52124
9 changed files with 398 additions and 7 deletions
  1. 3 0
      controllers/base.go
  2. 81 3
      controllers/book.go
  3. 41 0
      controllers/manager.go
  4. 88 0
      models/book.go
  5. 2 0
      models/book_result.go
  6. 133 2
      models/comment.go
  7. 14 0
      models/document.go
  8. 6 2
      models/errors.go
  9. 30 0
      utils/krand.go

+ 3 - 0
controllers/base.go

@@ -83,3 +83,6 @@ func (c *BaseController) ExecuteViewPathTemplate(tplName string,data interface{}
 	return buf.String(),nil
 }
 
+func (c *BaseController) BaseUrl() string {
+	return c.Ctx.Input.Scheme() + "://" + c.Ctx.Request.Host
+}

+ 81 - 3
controllers/book.go

@@ -12,6 +12,7 @@ import (
 	"github.com/lifei6671/godoc/utils"
 	"github.com/astaxie/beego"
 	"github.com/astaxie/beego/orm"
+	"github.com/astaxie/beego/logs"
 )
 
 type BookController struct {
@@ -123,6 +124,7 @@ func (c *BookController) Users() {
 	}
 }
 
+// 参加参与用户.
 func (c *BookController) AddMember()  {
 	identify := c.GetString("identify")
 	account := c.GetString("account")
@@ -167,7 +169,7 @@ func (c *BookController) AddMember()  {
 	c.JsonResult(500,err.Error())
 }
 
-
+// 创建项目.
 func (c *BookController) Create() {
 
 	if c.Ctx.Input.IsPost() {
@@ -230,11 +232,87 @@ func (c *BookController) Create() {
 // Edit 编辑项目.
 func (p *BookController) Edit() {
 	p.TplName = "book/edit.tpl"
+
+}
+
+//创建访问来令牌
+func (c *BookController) CreateToken() {
+	book_id,_ := c.GetInt("book_id",0)
+
+	if book_id <= 0{
+		c.JsonResult(6001,"参数错误")
+	}
+
+	book := models.NewBook()
+
+	if err := book.Find(book_id);err != nil {
+		c.JsonResult(6001,"项目不存在")
+	}
+	bookResult ,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,"项目不存在")
+		}
+		logs.Error("生成阅读令牌失败 =>",err)
+		c.JsonResult(6002,err.Error())
+	}
+	//必须是管理员或创始人才能删除项目
+	if bookResult.RoleId != 0 && bookResult.RoleId != 1 {
+		c.JsonResult(403,"权限不足")
+	}
+	if bookResult.PrivatelyOwned == 0 {
+		c.JsonResult(6001,"公开项目不能创建阅读令牌")
+	}
+
+	book.PrivateToken = utils.Krand(20,utils.KC_RAND_KIND_ALL)
+	if err := book.Update(); err != nil {
+		logs.Error("生成阅读令牌失败 => ",err)
+		c.JsonResult(6003,"生成阅读令牌失败")
+	}
+	c.JsonResult(0,"ok", c.BaseUrl() + "?token="+ book.PrivateToken)
 }
 
 // Delete 删除项目.
-func (p *BookController) Delete() {
-	p.StopRun()
+func (c *BookController) Delete() {
+	c.Prepare()
+
+	book_id,_ := c.GetInt("book_id",0)
+
+	if book_id <= 0{
+		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,"项目不存在")
+		}
+		logs.Error("删除项目 =>",err)
+		c.JsonResult(6002,err.Error())
+	}
+	//必须是管理员或创始人才能删除项目
+	if book.RoleId != 0 && book.RoleId != 1 {
+		c.JsonResult(403,"权限不足")
+	}
+
+	err = models.NewBook().ThoroughDeleteBook(book_id)
+
+	if err == orm.ErrNoRows {
+		c.JsonResult(6002,"项目不存在")
+	}
+	if err != nil {
+		logs.Error("删除项目 => ",err)
+		c.JsonResult(6003,"删除失败")
+	}
+	c.JsonResult(0,"ok")
 }
 
 // Transfer 转让项目.

+ 41 - 0
controllers/manager.go

@@ -11,6 +11,7 @@ import (
 	"github.com/astaxie/beego/logs"
 	"github.com/lifei6671/godoc/utils"
 	"github.com/lifei6671/godoc/models"
+	"github.com/astaxie/beego/orm"
 )
 
 type ManagerController struct {
@@ -145,11 +146,30 @@ func (c *ManagerController) Books()  {
 
 }
 
+// 删除项目.
 func (c *ManagerController) DeleteBook()  {
 	c.Prepare()
 	if c.Member.Role != 0 {
 		c.Abort("403")
 	}
+
+	book_id,_ := c.GetInt("book_id",0)
+
+	if book_id <= 0{
+		c.JsonResult(6001,"参数错误")
+	}
+	book := models.NewBook()
+
+	err := book.ThoroughDeleteBook(book_id)
+
+	if err == orm.ErrNoRows {
+		c.JsonResult(6002,"项目不存在")
+	}
+	if err != nil {
+		logs.Error("",err)
+		c.JsonResult(6003,"删除失败")
+	}
+	c.JsonResult(0,"ok")
 }
 
 func (c *ManagerController) Comments()  {
@@ -159,11 +179,30 @@ func (c *ManagerController) Comments()  {
 	}
 }
 
+//DeleteComment 标记评论为已删除
 func (c *ManagerController) DeleteComment()  {
 	c.Prepare()
 	if c.Member.Role != 0 {
 		c.Abort("403")
 	}
+	comment_id,_ := c.GetInt("comment_id",0)
+
+	if comment_id <= 0 {
+		c.JsonResult(6001,"参数错误")
+	}
+
+	comment := models.NewComment()
+
+	if err := comment.Find(comment_id); err != nil {
+		c.JsonResult(6002,"评论不存在")
+	}
+
+	comment.Approved = 3
+
+	if err := comment.Update("approved");err != nil {
+		c.JsonResult(6003,"删除评论失败")
+	}
+	c.JsonResult(0,"ok",comment)
 }
 
 
@@ -183,5 +222,7 @@ func (c *ManagerController) DeleteComment()  {
 
 
 
+
+
 
 

+ 88 - 0
models/book.go

@@ -22,6 +22,8 @@ type Book struct {
 	PrivatelyOwned int	`orm:"column(privately_owned);type(int);default(0)" json:"privately_owned"`
 	// 当项目是私有时的访问Token.
 	PrivateToken string 	`orm:"column(private_token);size(500);null" json:"private_token"`
+	//评论状态:0 正常/1 已删除
+	Status int 		`orm:"column(status);type(int);default(0)" json:"status"`
 	// DocCount 包含文档数量.
 	DocCount int		`orm:"column(doc_count);type(int)" json:"doc_count"`
 	// CommentStatus 评论设置的状态:open 为允许所有人评论,closed 为不允许评论, group_only 仅允许参与者评论 ,registered_only 仅允许注册者评论.
@@ -60,6 +62,15 @@ func (m *Book) Insert() error {
 	return err
 }
 
+func (m *Book) Find(id int) error {
+	if id <= 0 {
+		return ErrInvalidParameter
+	}
+	o := orm.NewOrm()
+
+	return o.Read(m)
+}
+
 func (m *Book) Update(cols... string) error  {
 	o := orm.NewOrm()
 
@@ -139,6 +150,83 @@ func (m *Book) FindToPager(pageIndex, pageSize ,memberId int) (books []BookResul
 	return
 }
 
+// 彻底删除项目.
+func (m *Book) ThoroughDeleteBook(id int) error {
+	if id <= 0{
+		return ErrInvalidParameter
+	}
+	o := orm.NewOrm()
+
+	m.BookId = id
+	if err := o.Read(m); err != nil {
+		return err
+	}
+	o.Begin()
+	sql1 := "DELETE FROM " + NewComment().TableNameWithPrefix() + " WHERE book_id = ?"
+
+	_,err := o.Raw(sql1,m.BookId).Exec()
+
+	if err != nil {
+		o.Rollback()
+		return err
+	}
+	sql2 := "DELETE FROM " + NewDocument().TableNameWithPrefix() + " WHERE book_id = ?"
+
+	_,err = o.Raw(sql2,m.BookId).Exec()
+
+	if err != nil {
+		o.Rollback()
+		return err
+	}
+	sql3 := "DELETE FROM " + m.TableNameWithPrefix() + " WHERE book_id = ?"
+
+	_,err = o.Raw(sql3).Exec()
+
+	if err != nil {
+		o.Rollback()
+		return err
+	}
+	sql4 := "DELETE FROM " + NewRelationship() + " WHERE book_id = ?"
+
+	_,err = o.Raw(sql4).Exec()
+
+	if err != nil {
+		o.Rollback()
+		return err
+	}
+
+	return o.Commit()
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 

+ 2 - 0
models/book_result.go

@@ -25,6 +25,7 @@ type BookResult struct {
 	MemberId int            `json:"member_id"`
 	RoleId int        	`json:"role_id"`
 	RoleName string 	`json:"role_name"`
+	Status int
 
 	LastModifyText string 	`json:"last_modify_text"`
 }
@@ -81,6 +82,7 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
 	m.ModifyTime = book.ModifyTime
 	m.Cover = book.Cover
 	m.Label = book.Label
+	m.Status = book.Status
 
 	m.MemberId = relationship.MemberId
 	m.RoleId = relationship.RoleId

+ 133 - 2
models/comment.go

@@ -1,10 +1,16 @@
 package models
 
-import "time"
+import (
+	"time"
+	"github.com/lifei6671/godoc/conf"
+	"github.com/astaxie/beego/orm"
+	"errors"
+)
 
 //Comment struct
 type Comment struct {
 	CommentId int			`orm:"pk;auto;unique;column(comment_id)" json:"comment_id"`
+	BookId int			`orm:"column(book_id);type(int)" json:"book_id"`
 	// DocumentId 评论所属的文档.
 	DocumentId int			`orm:"column(document_id);type(int)" json:"document_id"`
 	// Author 评论作者.
@@ -17,7 +23,7 @@ type Comment struct {
 	CommentDate time.Time		`orm:"type(datetime);column(comment_date);auto_now_add" json:"comment_date"`
 	//Content 评论内容.
 	Content string			`orm:"column(content);size(2000)" json:"content"`
-	// Approved 评论状态:0 待审核/1 已审核/2 垃圾评论
+	// Approved 评论状态:0 待审核/1 已审核/2 垃圾评论/ 3 已删除
 	Approved int			`orm:"column(approved);type(int)" json:"approved"`
 	// UserAgent 评论者浏览器内容
 	UserAgent string		`orm:"column(user_agent);size(500)" json:"user_agent"`
@@ -33,4 +39,129 @@ func (m *Comment) TableName() string {
 func (m *Comment) TableEngine() string {
 	return "INNODB"
 }
+
+func (m *Comment) TableNameWithPrefix() string  {
+	return conf.GetDatabasePrefix() + m.TableName()
+}
+
+func NewComment() *Comment {
+	return &Comment{}
+}
+func (m *Comment) Find(id int) error {
+	if id <= 0 {
+		return ErrInvalidParameter
+	}
+	o := orm.NewOrm()
+	return o.Read(m)
+}
+
+func (m *Comment) Update(cols... string)  error {
+	o := orm.NewOrm()
+
+	_,err := o.Update(m,cols)
+
+	return err
+}
+
+//Insert 添加一条评论.
+func (m *Comment) Insert() error {
+	if m.DocumentId <= 0{
+		return errors.New("评论文档不存在")
+	}
+	if m.Content == "" {
+		return ErrCommentContentNotEmpty
+	}
+
+	o := orm.NewOrm()
+
+	if m.CommentId > 0 {
+		comment := NewComment()
+		//如果父评论不存在
+		if err := o.Read(comment); err != nil {
+			return err
+		}
+	}
+
+	document := NewDocument()
+	//如果评论的文档不存在
+	if err := document.Find(m.DocumentId); err != nil {
+		return err
+	}
+	book := NewBook()
+	//如果评论的项目不存在
+	if err := book.Find(document.BookId); err != nil {
+		return err
+	}
+	//如果已关闭评论
+	if book.CommentStatus == "closed"{
+		return ErrCommentClosed
+	}
+	if book.CommentStatus == "registered_only" && m.MemberId <= 0{
+		return ErrPermissionDenied
+	}
+	//如果仅参与者评论
+	if book.CommentStatus == "group_only" {
+		if m.MemberId <= 0{
+			return ErrPermissionDenied
+		}
+		rel := NewRelationship()
+		if _,err := rel.FindForRoleId(book.BookId,m.MemberId);err != nil {
+			return ErrPermissionDenied
+		}
+	}
+
+	if m.MemberId > 0 {
+		member := NewMember()
+		//如果用户不存在
+		if err := member.Find(m.MemberId) ; err != nil {
+			return ErrMemberNoExist
+		}
+		//如果用户被禁用
+		if member.Status == 1 {
+			return ErrMemberDisabled
+		}
+	}else if m.Author == "" {
+		m.Author = "[匿名用户]"
+	}
+	m.BookId = book.BookId
+	_,err := o.Insert(m)
+
+	return err
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 

+ 14 - 0
models/document.go

@@ -3,6 +3,7 @@ package models
 import (
 	"time"
 	"github.com/lifei6671/godoc/conf"
+	"github.com/astaxie/beego/orm"
 )
 
 // Document struct.
@@ -44,8 +45,21 @@ func NewDocument() *Document  {
 	return &Document{}
 }
 
+func (m *Document) Find(id int) error {
+	if id <= 0 {
+		return ErrInvalidParameter
+	}
+	o := orm.NewOrm()
 
 
+	err := o.Read(m)
+
+	if err == orm.ErrNoRows{
+		return ErrDataNotExist
+	}
+	return nil
+}
+
 
 
 

+ 6 - 2
models/errors.go

@@ -6,13 +6,17 @@ import "errors"
 var(
 	// ErrMemberNoExist 用户不存在.
 	ErrMemberNoExist = errors.New("用户不存在")
+	ErrMemberDisabled = errors.New("用户被禁用")
 	// ErrorMemberPasswordError 密码错误.
 	ErrorMemberPasswordError = errors.New("用户密码错误")
-	// ErrServerAlreadyExist 指定的服务已存在.
-	ErrServerAlreadyExist = errors.New("服务已存在")
+	// ErrDataNotExist 指定的服务已存在.
+	ErrDataNotExist = errors.New("数据不存在")
 
 	// ErrInvalidParameter 参数错误.
 	ErrInvalidParameter = errors.New("Invalid parameter")
 
 	ErrPermissionDenied = errors.New("Permission denied")
+
+	ErrCommentClosed = errors.New("评论已关闭")
+	ErrCommentContentNotEmpty = errors.New("评论内容不能为空")
 )

+ 30 - 0
utils/krand.go

@@ -0,0 +1,30 @@
+package utils
+
+import (
+	"time"
+	"math/rand"
+)
+
+
+const (
+	KC_RAND_KIND_NUM   = 0  // 纯数字
+	KC_RAND_KIND_LOWER = 1  // 小写字母
+	KC_RAND_KIND_UPPER = 2  // 大写字母
+	KC_RAND_KIND_ALL   = 3  // 数字、大小写字母
+)
+
+// 随机字符串
+func Krand(size int, kind int) []byte {
+	ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
+	is_all := kind > 2 || kind < 0
+	rand.Seed(time.Now().UnixNano())
+	for i :=0; i < size; i++ {
+		if is_all { // random ikind
+			ikind = rand.Intn(3)
+		}
+		scope, base := kinds[ikind][0], kinds[ikind][1]
+		result[i] = uint8(base+rand.Intn(scope))
+	}
+
+	return result
+}