1、实现富文本编辑器

2、实现文档转换为PDF、MOBI、EPUB、Word格式
3、实现登录后跳转到来源地址
This commit is contained in:
Minho
2018-01-26 17:17:38 +08:00
parent e1ec6bb788
commit 882d93e7b0
57 changed files with 1572 additions and 1475 deletions

View File

@@ -127,7 +127,7 @@ func (m *Attachment) FindToPager(pageIndex, pageSize int) (attachList []*Attachm
} else {
attach.DocumentName = "[不存在]"
}
attach.LocalHttpPath = strings.Replace(item.FilePath,"\\","/",-1)
attach.LocalHttpPath = strings.Replace(item.FilePath, "\\", "/", -1)
attachList = append(attachList, attach)
}

View File

@@ -8,27 +8,27 @@ import (
type AttachmentResult struct {
Attachment
IsExist bool
BookName string
DocumentName string
IsExist bool
BookName string
DocumentName string
FileShortSize string
Account string
Account string
LocalHttpPath string
}
func NewAttachmentResult() *AttachmentResult {
return &AttachmentResult{ IsExist : false }
return &AttachmentResult{IsExist: false}
}
func (m *AttachmentResult) Find(id int) (*AttachmentResult,error) {
func (m *AttachmentResult) Find(id int) (*AttachmentResult, error) {
o := orm.NewOrm()
attach := NewAttachment()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("attachment_id",id).One(attach)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("attachment_id", id).One(attach)
if err != nil {
return m,err
return m, err
}
m.Attachment = *attach
@@ -50,12 +50,12 @@ func (m *AttachmentResult) Find(id int) (*AttachmentResult,error) {
if attach.CreateAt > 0 {
member := NewMember()
if e := o.QueryTable(member.TableNameWithPrefix()).Filter("member_id",attach.CreateAt).One(member,"account");e == nil {
if e := o.QueryTable(member.TableNameWithPrefix()).Filter("member_id", attach.CreateAt).One(member, "account"); e == nil {
m.Account = member.Account
}
}
m.FileShortSize = utils.FormatBytes(int64(attach.FileSize))
m.LocalHttpPath = strings.Replace(m.FilePath,"\\","/",-1)
m.LocalHttpPath = strings.Replace(m.FilePath, "\\", "/", -1)
return m,nil
}
return m, nil
}

View File

@@ -1,6 +1,4 @@
package models
type Model struct {
}

View File

@@ -4,9 +4,9 @@ import "time"
//博文表
type Blog struct {
BlogId int
BlogId int
BlogTitle string
MemberId int
MemberId int
//文字摘要
BlogExcerpt string
//文章内容
@@ -22,4 +22,4 @@ type Blog struct {
ModifyAt int
//创建时间
Created time.Time
}
}

View File

@@ -3,11 +3,14 @@ package models
import (
"time"
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"fmt"
"os"
"path/filepath"
"strconv"
)
// Book struct .
@@ -16,17 +19,15 @@ type Book struct {
// BookName 项目名称.
BookName string `orm:"column(book_name);size(500)" json:"book_name"`
// Identify 项目唯一标识.
Identify string `orm:"column(identify);size(100);unique" json:"identify"`
Identify string `orm:"column(identify);size(100);unique" json:"identify"`
//是否是自动发布 0 否/1 是
AutoRelease int `orm:"column(auto_release);type(int);default(0)" json:"auto_release"`
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 string `orm:"column(description);size(2000)" json:"description"`
//发行公司
Publisher string `orm:"column(publisher);size(500)" json:"publisher"`
//是否缓存导出的电子书,如果缓存可能会出现导出的文件不是最新的。 0 为不缓存
IsCacheEBook int `orm:"column(is_cache_ebook);type(int);default(0)" json:"is_cache_ebook"`
Label string `orm:"column(label);size(500)" json:"label"`
Publisher string `orm:"column(publisher);size(500)" json:"publisher"`
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.
@@ -122,7 +123,7 @@ func (m *Book) Update(cols ...string) error {
temp := NewBook()
temp.BookId = m.BookId
if err := o.Read(temp);err != nil {
if err := o.Read(temp); err != nil {
return err
}
@@ -185,7 +186,7 @@ func (m *Book) FindToPager(pageIndex, pageSize, memberId int) (books []*BookResu
" LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel ON book.book_id=rel.book_id AND rel.member_id = ?" +
" LEFT JOIN " + relationship.TableNameWithPrefix() + " AS rel1 ON book.book_id=rel1.book_id AND rel1.role_id=0" +
" LEFT JOIN " + NewMember().TableNameWithPrefix() + " AS m ON rel1.member_id=m.member_id " +
" WHERE rel.relationship_id > 0 ORDER BY book.order_index DESC,book.book_id DESC LIMIT " + fmt.Sprintf("%d,%d",offset,pageSize)
" WHERE rel.relationship_id > 0 ORDER BY book.order_index DESC,book.book_id DESC LIMIT " + fmt.Sprintf("%d,%d", offset, pageSize)
_, err = o.Raw(sql2, memberId).QueryRows(&books)
if err != nil {
@@ -261,6 +262,8 @@ func (m *Book) ThoroughDeleteBook(id int) error {
NewLabel().InsertOrUpdateMulti(m.Label)
}
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(id)))
return o.Commit()
}
@@ -320,7 +323,7 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
if member_id > 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 ?"
err = o.Raw(sql1, member_id,keyword).QueryRow(&totalCount)
err = o.Raw(sql1, member_id, keyword).QueryRow(&totalCount)
if err != nil {
return
}
@@ -330,12 +333,12 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
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 ?,?`
_, err = o.Raw(sql2, member_id,keyword, offset, pageSize).QueryRows(&books)
_, err = o.Raw(sql2, member_id, keyword, offset, pageSize).QueryRows(&books)
return
} else {
count, err1 := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("privately_owned", 0).Filter("label__icontains",keyword).Count()
count, err1 := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("privately_owned", 0).Filter("label__icontains", keyword).Count()
if err1 != nil {
err = err1
@@ -348,14 +351,13 @@ func (m *Book) FindForLabelToPager(keyword string, pageIndex, pageSize, member_i
LEFT JOIN md_members AS member ON rel.member_id = member.member_id
WHERE book.privately_owned = 0 AND book.label LIKE ? ORDER BY order_index DESC ,book.book_id DESC LIMIT ?,?`
_, err = o.Raw(sql,keyword, offset, pageSize).QueryRows(&books)
_, err = o.Raw(sql, keyword, offset, pageSize).QueryRows(&books)
return
}
}
//重置文档数量
func (m *Book) ResetDocumentNumber(book_id int) {
o := orm.NewOrm()

View File

@@ -1,64 +1,64 @@
package models
import (
"time"
"bytes"
"github.com/astaxie/beego/orm"
"github.com/astaxie/beego/logs"
"github.com/lifei6671/mindoc/conf"
"strings"
"github.com/lifei6671/mindoc/converter"
"strconv"
"github.com/russross/blackfriday"
"path/filepath"
"github.com/astaxie/beego"
"time"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"encoding/base64"
"github.com/PuerkitoBio/goquery"
"github.com/astaxie/beego"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/converter"
"github.com/lifei6671/mindoc/utils"
"github.com/russross/blackfriday"
)
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"`
Publisher string `json:"publisher"`
IsCacheEBook bool `json:"is_cache_ebook"`
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"`
Theme string `json:"theme"`
Label string `json:"label"`
MemberId int `json:"member_id"`
Editor string `json:"editor"`
AutoRelease bool `json:"auto_release"`
BookId int `json:"book_id"`
BookName string `json:"book_name"`
Identify string `json:"identify"`
OrderIndex int `json:"order_index"`
Description string `json:"description"`
Publisher string `json:"publisher"`
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"`
Theme string `json:"theme"`
Label string `json:"label"`
MemberId int `json:"member_id"`
Editor string `json:"editor"`
AutoRelease bool `json:"auto_release"`
RelationshipId int `json:"relationship_id"`
RoleId int `json:"role_id"`
RoleName string `json:"role_name"`
Status int
RelationshipId int `json:"relationship_id"`
RoleId int `json:"role_id"`
RoleName string `json:"role_name"`
Status int
LastModifyText string `json:"last_modify_text"`
IsDisplayComment bool `json:"is_display_comment"`
LastModifyText string `json:"last_modify_text"`
IsDisplayComment bool `json:"is_display_comment"`
}
func NewBookResult() *BookResult {
return &BookResult{}
}
// 根据项目标识查询项目以及指定用户权限的信息.
func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,error) {
func (m *BookResult) FindByIdentify(identify string, member_id int) (*BookResult, error) {
if identify == "" || member_id <= 0 {
return m,ErrInvalidParameter
return m, ErrInvalidParameter
}
o := orm.NewOrm()
@@ -93,11 +93,10 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
m = NewBookResult().ToBookResult(*book)
m.CreateName = member.Account
m.MemberId = relationship.MemberId
m.RoleId = relationship.RoleId
m.RelationshipId = relationship.RelationshipId
m.CreateName = member.Account
m.MemberId = relationship.MemberId
m.RoleId = relationship.RoleId
m.RelationshipId = relationship.RelationshipId
if m.RoleId == conf.BookFounder {
m.RoleName = "创始人"
@@ -123,10 +122,10 @@ func (m *BookResult) FindByIdentify(identify string,member_id int) (*BookResult,
return m, nil
}
func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*BookResult,totalCount int,err error) {
func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*BookResult, totalCount int, err error) {
o := orm.NewOrm()
count,err := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
count, err := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
if err != nil {
return
@@ -140,9 +139,9 @@ func (m *BookResult) FindToPager(pageIndex, pageSize int) (books []*BookResult,t
LEFT JOIN md_members AS m ON rel.member_id = m.member_id
ORDER BY book.order_index DESC ,book.book_id DESC LIMIT ?,?`
offset := (pageIndex -1 )* pageSize
offset := (pageIndex - 1) * pageSize
_,err = o.Raw(sql,offset,pageSize).QueryRows(&books)
_, err = o.Raw(sql, offset, pageSize).QueryRows(&books)
return
}
@@ -169,7 +168,6 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
m.Theme = book.Theme
m.AutoRelease = book.AutoRelease == 1
m.Publisher = book.Publisher
m.IsCacheEBook = book.IsCacheEBook == 1
if book.Theme == "" {
m.Theme = "default"
@@ -180,128 +178,139 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
return m
}
func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) {
func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
convertBookResult := ConvertBookResult{}
outputPath := filepath.Join(beego.AppConfig.DefaultString("book_output_path","cache"),sessionId,strconv.Itoa(m.BookId))
if m.IsCacheEBook {
outputPath = filepath.Join(beego.AppConfig.DefaultString("book_output_path","cache"),strconv.Itoa(m.BookId))
outputPath := filepath.Join(conf.WorkingDirectory,"uploads","books", strconv.Itoa(m.BookId))
viewPath := beego.BConfig.WebConfig.ViewsPath
pdfpath := filepath.Join(outputPath, "book.pdf")
epubpath := filepath.Join(outputPath, "book.epub")
mobipath := filepath.Join(outputPath, "book.mobi")
docxpath := filepath.Join(outputPath, "book.docx")
//先将转换的文件储存到临时目录
tempOutputPath := filepath.Join(os.TempDir(),"sessionId") //filepath.Abs(filepath.Join("cache", sessionId))
os.MkdirAll(outputPath, 0766)
os.MkdirAll(tempOutputPath, 0766)
if utils.FileExists(pdfpath) && utils.FileExists(epubpath) && utils.FileExists(mobipath) && utils.FileExists(docxpath) {
convertBookResult.EpubPath = epubpath
convertBookResult.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath
convertBookResult.WordPath = docxpath
return convertBookResult, nil
}
if m.IsCacheEBook {
pdfpath := filepath.Join(outputPath,"output","book.pdf")
epubpath := filepath.Join(outputPath,"output","book.epub")
mobipath := filepath.Join(outputPath,"output","book.mobi")
if utils.FileExists(pdfpath) && utils.FileExists(epubpath) && utils.FileExists(mobipath){
convertBookResult.EpubPath = epubpath
convertBookResult.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath
return convertBookResult,nil
}
}
docs, err := NewDocument().FindListByBookId(m.BookId)
if err != nil {
return convertBookResult,err
return convertBookResult, err
}
tocList := make([]converter.Toc,0)
tocList := make([]converter.Toc, 0)
for _, item := range docs {
if item.ParentId == 0 {
toc := converter.Toc{
Id: item.DocumentId,
Link: strconv.Itoa(item.DocumentId) + ".html",
Pid: item.ParentId,
Id: item.DocumentId,
Link: strconv.Itoa(item.DocumentId) + ".html",
Pid: item.ParentId,
Title: item.DocumentName,
}
tocList = append(tocList,toc)
tocList = append(tocList, toc)
}
}
for _, item := range docs {
if item.ParentId != 0 {
toc := converter.Toc{
Id: item.DocumentId,
Link: strconv.Itoa(item.DocumentId) + ".html",
Pid: item.ParentId,
Id: item.DocumentId,
Link: strconv.Itoa(item.DocumentId) + ".html",
Pid: item.ParentId,
Title: item.DocumentName,
}
tocList = append(tocList,toc)
tocList = append(tocList, toc)
}
}
ebookConfig := converter.Config{
Charset : "utf-8",
Cover : m.Cover,
Timestamp : time.Now().Format("2006-01-02 15:04:05"),
Description : string(blackfriday.MarkdownBasic([]byte(m.Description))),
Footer : "<p style='color:#8E8E8E;font-size:12px;'>本文档使用 <a href='https://www.iminho.me' style='text-decoration:none;color:#1abc9c;font-weight:bold;'>MinDoc</a> 构建 <span style='float:right'>- _PAGENUM_ -</span></p>",
Header : "<p style='color:#8E8E8E;font-size:12px;'>_SECTION_</p>",
Identifier : "",
Language : "zh-CN",
Creator : m.CreateName,
Publisher : m.Publisher,
Contributor : m.Publisher,
Title : m.BookName,
Format: []string{"epub", "mobi", "pdf"},
FontSize : "14",
PaperSize : "a4",
MarginLeft : "72",
MarginRight : "72",
MarginTop : "72",
MarginBottom : "72",
Toc : tocList,
More : []string{},
Charset: "utf-8",
Cover: m.Cover,
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
Description: string(blackfriday.MarkdownBasic([]byte(m.Description))),
Footer: "<p style='color:#8E8E8E;font-size:12px;'>本文档使用 <a href='https://www.iminho.me' style='text-decoration:none;color:#1abc9c;font-weight:bold;'>MinDoc</a> 构建 <span style='float:right'>- _PAGENUM_ -</span></p>",
Header: "<p style='color:#8E8E8E;font-size:12px;'>_SECTION_</p>",
Identifier: "",
Language: "zh-CN",
Creator: m.CreateName,
Publisher: m.Publisher,
Contributor: m.Publisher,
Title: m.BookName,
Format: []string{"epub", "mobi", "pdf", "docx"},
FontSize: "14",
PaperSize: "a4",
MarginLeft: "72",
MarginRight: "72",
MarginTop: "72",
MarginBottom: "72",
Toc: tocList,
More: []string{},
}
os.MkdirAll(outputPath, 0766)
if outputPath, err = filepath.Abs(outputPath); err != nil {
if tempOutputPath, err = filepath.Abs(tempOutputPath); err != nil {
beego.Error("导出目录配置错误:" + err.Error())
return convertBookResult,err
return convertBookResult, err
}
viewPath := beego.BConfig.WebConfig.ViewsPath
baseUrl := beego.AppConfig.DefaultString("baseurl","")
for _,item := range docs {
for _, item := range docs {
name := strconv.Itoa(item.DocumentId)
fpath := filepath.Join(outputPath,name + ".html")
fpath := filepath.Join(tempOutputPath, name+".html")
f, err := os.OpenFile(fpath, os.O_CREATE|os.O_RDWR, 0777)
if err != nil {
return convertBookResult,err
return convertBookResult, err
}
var buf bytes.Buffer
if err := beego.ExecuteViewPathTemplate(&buf,"document/export.tpl",viewPath,map[string]interface{}{"Model": m, "Lists": item, "BaseUrl": baseUrl}); err != nil {
return convertBookResult,err
if err := beego.ExecuteViewPathTemplate(&buf, "document/export.tpl", viewPath, map[string]interface{}{"Model": m, "Lists": item, "BaseUrl": conf.BaseUrl}); err != nil {
return convertBookResult, err
}
html := buf.String()
if err != nil {
f.Close()
return convertBookResult,err
return convertBookResult, err
}
bufio := bytes.NewReader(buf.Bytes())
doc, err := goquery.NewDocumentFromReader(bufio)
doc.Find("img").Each(func(i int, contentSelection *goquery.Selection) {
if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/uploads/") {
contentSelection.SetAttr("src", baseUrl + src)
if src, ok := contentSelection.Attr("src"); ok && strings.HasPrefix(src, "/") {
//contentSelection.SetAttr("src", baseUrl + src)
spath := filepath.Join(conf.WorkingDirectory, src)
if ff, e := ioutil.ReadFile(spath); e == nil {
encodeString := base64.StdEncoding.EncodeToString(ff)
src = "data:image/" + filepath.Ext(src) + ";base64," + encodeString
contentSelection.SetAttr("src", src)
}
}
})
html, err = doc.Html()
if err != nil {
f.Close()
return convertBookResult,err
return convertBookResult, err
}
// html = strings.Replace(html, "<img src=\"/uploads", "<img src=\"" + c.BaseUrl() + "/uploads", -1)
@@ -310,35 +319,29 @@ func (m *BookResult) Converter(sessionId string) (ConvertBookResult,error) {
f.Close()
}
eBookConverter := &converter.Converter{
BasePath : outputPath,
Config : ebookConfig,
Debug : false,
BasePath: tempOutputPath,
Config: ebookConfig,
Debug: true,
}
if err := eBookConverter.Convert();err != nil {
beego.Error("转换文件错误:" + m.BookName +" => "+ err.Error())
return convertBookResult,err
if err := eBookConverter.Convert(); err != nil {
beego.Error("转换文件错误:" + m.BookName + " => " + err.Error())
return convertBookResult, err
}
convertBookResult.MobiPath = filepath.Join(outputPath,"output","book.mobi")
convertBookResult.PDFPath = filepath.Join(outputPath,"output","book.pdf")
convertBookResult.EpubPath = filepath.Join(outputPath,"output","book.epub")
return convertBookResult,nil
beego.Info("文档转换完成:" + m.BookName)
defer func(p string) {
os.RemoveAll(p)
}(tempOutputPath)
utils.CopyFile(mobipath, filepath.Join(tempOutputPath, "output", "book.mobi"))
utils.CopyFile(pdfpath, filepath.Join(tempOutputPath, "output", "book.pdf"))
utils.CopyFile(epubpath, filepath.Join(tempOutputPath, "output", "book.epub"))
utils.CopyFile(docxpath, filepath.Join(tempOutputPath, "output", "book.docx"))
convertBookResult.MobiPath = mobipath
convertBookResult.PDFPath = pdfpath
convertBookResult.EpubPath = epubpath
convertBookResult.WordPath = docxpath
return convertBookResult, nil
}

View File

@@ -1,76 +1,77 @@
package models
import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"errors"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
)
//Comment struct
type Comment struct {
CommentId int `orm:"pk;auto;unique;column(comment_id)" json:"comment_id"`
Floor int `orm:"column(floor);type(unsigned);default(0)" json:"floor"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
CommentId int `orm:"pk;auto;unique;column(comment_id)" json:"comment_id"`
Floor int `orm:"column(floor);type(unsigned);default(0)" json:"floor"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
// DocumentId 评论所属的文档.
DocumentId int `orm:"column(document_id);type(int)" json:"document_id"`
DocumentId int `orm:"column(document_id);type(int)" json:"document_id"`
// Author 评论作者.
Author string `orm:"column(author);size(100)" json:"author"`
Author string `orm:"column(author);size(100)" json:"author"`
//MemberId 评论用户ID.
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
// IPAddress 评论者的IP地址
IPAddress string `orm:"column(ip_address);size(100)" json:"ip_address"`
IPAddress string `orm:"column(ip_address);size(100)" json:"ip_address"`
// 评论日期.
CommentDate time.Time `orm:"type(datetime);column(comment_date);auto_now_add" json:"comment_date"`
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"`
Content string `orm:"column(content);size(2000)" json:"content"`
// Approved 评论状态0 待审核/1 已审核/2 垃圾评论/ 3 已删除
Approved int `orm:"column(approved);type(int)" json:"approved"`
Approved int `orm:"column(approved);type(int)" json:"approved"`
// UserAgent 评论者浏览器内容
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
// Parent 评论所属父级
ParentId int `orm:"column(parent_id);type(int);default(0)" json:"parent_id"`
AgreeCount int `orm:"column(agree_count);type(int);default(0)" json:"agree_count"`
AgainstCount int `orm:"column(against_count);type(int);default(0)" json:"against_count"`
ParentId int `orm:"column(parent_id);type(int);default(0)" json:"parent_id"`
AgreeCount int `orm:"column(agree_count);type(int);default(0)" json:"agree_count"`
AgainstCount int `orm:"column(against_count);type(int);default(0)" json:"against_count"`
}
// TableName 获取对应数据库表名.
func (m *Comment) TableName() string {
return "comments"
}
// TableEngine 获取数据使用的引擎.
func (m *Comment) TableEngine() string {
return "INNODB"
}
func (m *Comment) TableNameWithPrefix() string {
func (m *Comment) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
}
func NewComment() *Comment {
return &Comment{}
}
func (m *Comment) Find(id int) (*Comment,error) {
func (m *Comment) Find(id int) (*Comment, error) {
if id <= 0 {
return m,ErrInvalidParameter
return m, ErrInvalidParameter
}
o := orm.NewOrm()
err := o.Read(m)
err := o.Read(m)
return m,err
return m, err
}
func (m *Comment) Update(cols... string) error {
func (m *Comment) Update(cols ...string) error {
o := orm.NewOrm()
_,err := o.Update(m,cols...)
_, err := o.Update(m, cols...)
return err
}
//Insert 添加一条评论.
func (m *Comment) Insert() error {
if m.DocumentId <= 0{
if m.DocumentId <= 0 {
return errors.New("评论文档不存在")
}
if m.Content == "" {
@@ -89,28 +90,28 @@ func (m *Comment) Insert() error {
document := NewDocument()
//如果评论的文档不存在
if _,err := document.Find(m.DocumentId); err != nil {
if _, err := document.Find(m.DocumentId); err != nil {
return err
}
book ,err := NewBook().Find(document.BookId);
book, err := NewBook().Find(document.BookId)
//如果评论的项目不存在
if err != nil {
return err
}
//如果已关闭评论
if book.CommentStatus == "closed"{
if book.CommentStatus == "closed" {
return ErrCommentClosed
}
if book.CommentStatus == "registered_only" && m.MemberId <= 0{
if book.CommentStatus == "registered_only" && m.MemberId <= 0 {
return ErrPermissionDenied
}
//如果仅参与者评论
if book.CommentStatus == "group_only" {
if m.MemberId <= 0{
if m.MemberId <= 0 {
return ErrPermissionDenied
}
rel := NewRelationship()
if _,err := rel.FindForRoleId(book.BookId,m.MemberId);err != nil {
if _, err := rel.FindForRoleId(book.BookId, m.MemberId); err != nil {
return ErrPermissionDenied
}
}
@@ -118,51 +119,18 @@ func (m *Comment) Insert() error {
if m.MemberId > 0 {
member := NewMember()
//如果用户不存在
if _,err := member.Find(m.MemberId) ; err != nil {
if _, err := member.Find(m.MemberId); err != nil {
return ErrMemberNoExist
}
//如果用户被禁用
if member.Status == 1 {
return ErrMemberDisabled
}
}else if m.Author == "" {
} else if m.Author == "" {
m.Author = "[匿名用户]"
}
m.BookId = book.BookId
_,err = o.Insert(m)
_, err = o.Insert(m)
return err
}

View File

@@ -4,11 +4,11 @@ import "github.com/astaxie/beego/orm"
type CommentResult struct {
Comment
Author string `json:"author"`
ReplyAccount string `json:"reply_account"`
Author string `json:"author"`
ReplyAccount string `json:"reply_account"`
}
func (m *CommentResult) FindForDocumentToPager(doc_id, page_index,page_size int) (comments []*CommentResult,totalCount int,err error) {
func (m *CommentResult) FindForDocumentToPager(doc_id, page_index, page_size int) (comments []*CommentResult, totalCount int, err error) {
o := orm.NewOrm()
@@ -25,12 +25,11 @@ FROM md_comments AS comment
WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10`
offset := (page_index - 1) * page_size
_,err = o.Raw(sql1,doc_id,offset, page_size).QueryRows(&comments)
_, err = o.Raw(sql1, doc_id, offset, page_size).QueryRows(&comments)
v,err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id",doc_id).Count()
v, err := o.QueryTable(m.TableNameWithPrefix()).Filter("document_id", doc_id).Count()
if err == nil {
totalCount = int(v)
@@ -38,4 +37,3 @@ WHERE comment.document_id = ? ORDER BY comment.comment_id DESC LIMIT 0,10`
return
}

View File

@@ -1,30 +1,31 @@
package models
import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
)
type CommentVote struct {
VoteId int `orm:"column(vote_id);pk;auto;unique" json:"vote_id"`
CommentId int `orm:"column(comment_id);type(int);index" json:"comment_id"`
CommentMemberId int `orm:"column(comment_member_id);type(int);index;default(0)" json:"comment_member_id"`
VoteMemberId int `orm:"column(vote_member_id);type(int);index" json:"vote_member_id"`
VoteState int `orm:"column(vote_state);type(int)" json:"vote_state"`
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
VoteId int `orm:"column(vote_id);pk;auto;unique" json:"vote_id"`
CommentId int `orm:"column(comment_id);type(int);index" json:"comment_id"`
CommentMemberId int `orm:"column(comment_member_id);type(int);index;default(0)" json:"comment_member_id"`
VoteMemberId int `orm:"column(vote_member_id);type(int);index" json:"vote_member_id"`
VoteState int `orm:"column(vote_state);type(int)" json:"vote_state"`
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
}
// TableName 获取对应数据库表名.
func (m *CommentVote) TableName() string {
return "comment_votes"
}
// TableEngine 获取数据使用的引擎.
func (m *CommentVote) TableEngine() string {
return "INNODB"
}
func (m *CommentVote) TableNameWithPrefix() string {
func (m *CommentVote) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
}
func (u *CommentVote) TableUnique() [][]string {
@@ -35,15 +36,15 @@ func (u *CommentVote) TableUnique() [][]string {
func NewCommentVote() *CommentVote {
return &CommentVote{}
}
func (m *CommentVote) InsertOrUpdate() (*CommentVote,error) {
func (m *CommentVote) InsertOrUpdate() (*CommentVote, error) {
o := orm.NewOrm()
if m.VoteId > 0 {
_,err := o.Update(m)
return m,err
}else{
_,err := o.Insert(m)
_, err := o.Update(m)
return m, err
} else {
_, err := o.Insert(m)
return m,err
return m, err
}
}
}

View File

@@ -2,7 +2,8 @@ package models
// 转换结果
type ConvertBookResult struct {
PDFPath string
PDFPath string
EpubPath string
MobiPath string
WordPath string
}

View File

@@ -3,34 +3,34 @@ package models
import "github.com/astaxie/beego/orm"
type Dashboard struct {
BookNumber int64 `json:"book_number"`
DocumentNumber int64 `json:"document_number"`
MemberNumber int64 `json:"member_number"`
CommentNumber int64 `json:"comment_number"`
AttachmentNumber int64 `json:"attachment_number"`
BookNumber int64 `json:"book_number"`
DocumentNumber int64 `json:"document_number"`
MemberNumber int64 `json:"member_number"`
CommentNumber int64 `json:"comment_number"`
AttachmentNumber int64 `json:"attachment_number"`
}
func NewDashboard() *Dashboard {
return &Dashboard{}
}
func (m *Dashboard) Query() (*Dashboard) {
func (m *Dashboard) Query() *Dashboard {
o := orm.NewOrm()
book_number,_ := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
book_number, _ := o.QueryTable(NewBook().TableNameWithPrefix()).Count()
m.BookNumber = book_number
document_count,_ := o.QueryTable(NewDocument().TableNameWithPrefix()).Count()
document_count, _ := o.QueryTable(NewDocument().TableNameWithPrefix()).Count()
m.DocumentNumber = document_count
member_number,_ := o.QueryTable(NewMember().TableNameWithPrefix()).Count()
member_number, _ := o.QueryTable(NewMember().TableNameWithPrefix()).Count()
m.MemberNumber = member_number
//comment_number,_ := o.QueryTable(NewComment().TableNameWithPrefix()).Count()
m.CommentNumber = 0
attachment_number,_ := o.QueryTable(NewAttachment().TableNameWithPrefix()).Count()
attachment_number, _ := o.QueryTable(NewAttachment().TableNameWithPrefix()).Count()
m.AttachmentNumber = attachment_number

View File

@@ -9,6 +9,9 @@ import (
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"strings"
"os"
"path/filepath"
"strconv"
)
// Document struct.
@@ -121,12 +124,12 @@ func (m *Document) RecursiveDocument(doc_id int) error {
}
//发布文档
func (m *Document) ReleaseContent(book_id int) {
func (m *Document) ReleaseContent(bookId int) {
o := orm.NewOrm()
var docs []*Document
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).All(&docs, "document_id", "content")
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", bookId).All(&docs, "document_id", "content")
if err != nil {
beego.Error("发布失败 => ", err)
@@ -134,12 +137,12 @@ func (m *Document) ReleaseContent(book_id int) {
}
for _, item := range docs {
item.Release = item.Content
attach_list, err := NewAttachment().FindListByDocumentId(item.DocumentId)
if err == nil && len(attach_list) > 0 {
attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
if err == nil && len(attachList) > 0 {
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>")
for _, attach := range attach_list {
if strings.HasPrefix(attach.HttpPath,"/"){
attach.HttpPath = strings.TrimSuffix(beego.AppConfig.DefaultString("baseurl",""),"/") + attach.HttpPath
for _, attach := range attachList {
if strings.HasPrefix(attach.HttpPath, "/") {
attach.HttpPath = strings.TrimSuffix(beego.AppConfig.DefaultString("baseurl", ""), "/") + attach.HttpPath
}
li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName)
@@ -151,6 +154,8 @@ func (m *Document) ReleaseContent(book_id int) {
_, err = o.Update(item, "release")
if err != nil {
beego.Error(fmt.Sprintf("发布失败 => %+v", item), err)
}else {
os.RemoveAll(filepath.Join(conf.WorkingDirectory,"uploads","books",strconv.Itoa(bookId)))
}
}
}

View File

@@ -23,14 +23,14 @@ type DocumentHistory struct {
}
type DocumentHistorySimpleResult struct {
HistoryId int `json:"history_id"`
ActionName string `json:"action_name"`
MemberId int `json:"member_id"`
Account string `json:"account"`
ModifyAt int `json:"modify_at"`
ModifyName string `json:"modify_name"`
ModifyTime time.Time `json:"modify_time"`
Version int64 `json:"version"`
HistoryId int `json:"history_id"`
ActionName string `json:"action_name"`
MemberId int `json:"member_id"`
Account string `json:"account"`
ModifyAt int `json:"modify_at"`
ModifyName string `json:"modify_name"`
ModifyTime time.Time `json:"modify_time"`
Version int64 `json:"version"`
}
// TableName 获取对应数据库表名.
@@ -50,12 +50,13 @@ func (m *DocumentHistory) TableNameWithPrefix() string {
func NewDocumentHistory() *DocumentHistory {
return &DocumentHistory{}
}
func (m *DocumentHistory) Find(id int) (*DocumentHistory,error) {
func (m *DocumentHistory) Find(id int) (*DocumentHistory, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id",id).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", id).One(m)
return m,err
return m, err
}
//清空指定文档的历史.
func (m *DocumentHistory) Clear(doc_id int) error {
o := orm.NewOrm()
@@ -66,19 +67,19 @@ func (m *DocumentHistory) Clear(doc_id int) error {
}
//删除历史.
func (m *DocumentHistory) Delete(history_id,doc_id int) error {
func (m *DocumentHistory) Delete(history_id, doc_id int) error {
o := orm.NewOrm()
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id",history_id).Filter("document_id",doc_id).Delete()
_, err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", history_id).Filter("document_id", doc_id).Delete()
return err
}
//恢复指定历史的文档.
func (m *DocumentHistory) Restore(history_id,doc_id,uid int) error {
func (m *DocumentHistory) Restore(history_id, doc_id, uid int) error {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", history_id).Filter("document_id",doc_id).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("history_id", history_id).Filter("document_id", doc_id).One(m)
if err != nil {
return err
@@ -113,17 +114,18 @@ func (m *DocumentHistory) Restore(history_id,doc_id,uid int) error {
return err
}
func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory,err error) {
func (m *DocumentHistory) InsertOrUpdate() (history *DocumentHistory, err error) {
o := orm.NewOrm()
history = m
if m.HistoryId > 0 {
_,err = o.Update(m)
}else{
_,err = o.Insert(m)
_, err = o.Update(m)
} else {
_, err = o.Insert(m)
}
return
}
//分页查询指定文档的历史.
func (m *DocumentHistory) FindToPager(doc_id, page_index, page_size int) (docs []*DocumentHistorySimpleResult, totalCount int, err error) {
@@ -139,7 +141,7 @@ LEFT JOIN md_members AS m1 ON history.member_id = m1.member_id
LEFT JOIN md_members AS m2 ON history.modify_at = m2.member_id
WHERE history.document_id = ? ORDER BY history.history_id DESC LIMIT ?,?;`
_, err = o.Raw(sql,doc_id,offset,page_size).QueryRows(&docs)
_, err = o.Raw(sql, doc_id, offset, page_size).QueryRows(&docs)
if err != nil {
return

View File

@@ -1,48 +1,49 @@
package models
import (
"github.com/astaxie/beego/orm"
"bytes"
"strconv"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"html/template"
"math"
"strconv"
)
type DocumentTree struct {
DocumentId int `json:"id"`
DocumentName string `json:"text"`
ParentId interface{} `json:"parent"`
Identify string `json:"identify"`
BookIdentify string `json:"-"`
Version int64 `json:"version"`
State *DocumentSelected `json:"state,omitempty"`
DocumentId int `json:"id"`
DocumentName string `json:"text"`
ParentId interface{} `json:"parent"`
Identify string `json:"identify"`
BookIdentify string `json:"-"`
Version int64 `json:"version"`
State *DocumentSelected `json:"state,omitempty"`
}
type DocumentSelected struct {
Selected bool `json:"selected"`
Opened bool `json:"opened"`
Selected bool `json:"selected"`
Opened bool `json:"opened"`
}
//获取项目的文档树状结构
func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree, error) {
o := orm.NewOrm()
trees := make([]*DocumentTree,0)
trees := make([]*DocumentTree, 0)
var docs []*Document
count ,err := o.QueryTable(m).Filter("book_id",book_id).OrderBy("order_sort","document_id").All(&docs,"document_id","version","document_name","parent_id","identify")
count, err := o.QueryTable(m).Filter("book_id", book_id).OrderBy("order_sort", "document_id").Limit(math.MaxInt32).All(&docs, "document_id", "version", "document_name", "parent_id", "identify")
if err != nil {
return trees,err
return trees, err
}
book,_ := NewBook().Find(book_id)
book, _ := NewBook().Find(book_id)
trees = make([]*DocumentTree,count)
trees = make([]*DocumentTree, count)
for index,item := range docs {
for index, item := range docs {
tree := &DocumentTree{}
if index == 0{
tree.State = &DocumentSelected{ Selected: true, Opened: true }
if index == 0 {
tree.State = &DocumentSelected{Selected: true, Opened: true}
}
tree.DocumentId = item.DocumentId
tree.Identify = item.Identify
@@ -50,7 +51,7 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
tree.BookIdentify = book.Identify
if item.ParentId > 0 {
tree.ParentId = item.ParentId
}else{
} else {
tree.ParentId = "#"
}
@@ -59,41 +60,41 @@ func (m *Document) FindDocumentTree(book_id int) ([]*DocumentTree,error){
trees[index] = tree
}
return trees,nil
return trees, nil
}
func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string,error) {
trees,err := m.FindDocumentTree(book_id)
func (m *Document) CreateDocumentTreeForHtml(book_id, selected_id int) (string, error) {
trees, err := m.FindDocumentTree(book_id)
if err != nil {
return "",err
return "", err
}
parent_id := getSelectedNode(trees,selected_id)
parent_id := getSelectedNode(trees, selected_id)
buf := bytes.NewBufferString("")
getDocumentTree(trees,0,selected_id,parent_id,buf)
getDocumentTree(trees, 0, selected_id, parent_id, buf)
return buf.String(), nil
return buf.String(),nil
}
//使用递归的方式获取指定ID的顶级ID
func getSelectedNode(array []*DocumentTree, parent_id int) int {
for _,item := range array {
if _,ok := item.ParentId.(string); ok && item.DocumentId == parent_id {
for _, item := range array {
if _, ok := item.ParentId.(string); ok && item.DocumentId == parent_id {
return item.DocumentId
}else if pid,ok := item.ParentId.(int); ok && item.DocumentId == parent_id{
return getSelectedNode(array,pid)
} else if pid, ok := item.ParentId.(int); ok && item.DocumentId == parent_id {
return getSelectedNode(array, pid)
}
}
return 0
return 0
}
func getDocumentTree(array []*DocumentTree,parent_id int,selected_id int,selected_parent_id int,buf *bytes.Buffer) {
func getDocumentTree(array []*DocumentTree, parent_id int, selected_id int, selected_parent_id int, buf *bytes.Buffer) {
buf.WriteString("<ul>")
for _,item := range array {
for _, item := range array {
pid := 0
if p, ok := item.ParentId.(int); ok {
@@ -138,14 +139,3 @@ func getDocumentTree(array []*DocumentTree,parent_id int,selected_id int,selecte
}
buf.WriteString("</ul>")
}

View File

@@ -5,16 +5,16 @@ import "errors"
var (
// ErrMemberNoExist 用户不存在.
ErrMemberNoExist = errors.New("用户不存在")
ErrMemberExist = errors.New("用户已存在")
ErrMemberDisabled = errors.New("用户被禁用")
ErrMemberEmailEmpty = errors.New("用户邮箱不能为空")
ErrMemberEmailExist = errors.New("用户邮箱已被使用")
ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字")
ErrMemberEmailFormatError = errors.New("邮箱格式不正确")
ErrMemberNoExist = errors.New("用户不存在")
ErrMemberExist = errors.New("用户已存在")
ErrMemberDisabled = errors.New("用户被禁用")
ErrMemberEmailEmpty = errors.New("用户邮箱不能为空")
ErrMemberEmailExist = errors.New("用户邮箱已被使用")
ErrMemberDescriptionTooLong = errors.New("用户描述必须小于500字")
ErrMemberEmailFormatError = errors.New("邮箱格式不正确")
ErrMemberPasswordFormatError = errors.New("密码必须在6-50个字符之间")
ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成且在3-50个字符")
ErrMemberRoleError = errors.New("用户权限不正确")
ErrMemberAccountFormatError = errors.New("账号只能由英文字母数字组成且在3-50个字符")
ErrMemberRoleError = errors.New("用户权限不正确")
// ErrorMemberPasswordError 密码错误.
ErrorMemberPasswordError = errors.New("用户密码错误")
//ErrorMemberAuthMethodInvalid 不支持此认证方式

View File

@@ -1,35 +1,36 @@
package models
import (
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"strings"
)
type Label struct {
LabelId int `orm:"column(label_id);pk;auto;unique;" json:"label_id"`
LabelName string `orm:"column(label_name);size(50);unique" json:"label_name"`
BookNumber int `orm:"column(book_number)" json:"book_number"`
LabelId int `orm:"column(label_id);pk;auto;unique;" json:"label_id"`
LabelName string `orm:"column(label_name);size(50);unique" json:"label_name"`
BookNumber int `orm:"column(book_number)" json:"book_number"`
}
// TableName 获取对应数据库表名.
func (m *Label) TableName() string {
return "label"
}
// TableEngine 获取数据使用的引擎.
func (m *Label) TableEngine() string {
return "INNODB"
}
func (m *Label)TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
func (m *Label) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
}
func NewLabel() *Label {
return &Label{}
}
func (m *Label) FindFirst(field string, value interface{}) (*Label,error){
func (m *Label) FindFirst(field string, value interface{}) (*Label, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, value).One(m)
@@ -41,27 +42,27 @@ func (m *Label) FindFirst(field string, value interface{}) (*Label,error){
func (m *Label) InsertOrUpdate(labelName string) error {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("label_name",labelName).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("label_name", labelName).One(m)
if err != nil && err != orm.ErrNoRows {
return err
}
count,_ := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("label__icontains",labelName).Count()
count, _ := o.QueryTable(NewBook().TableNameWithPrefix()).Filter("label__icontains", labelName).Count()
m.BookNumber = int(count)
m.LabelName = labelName
if err == orm.ErrNoRows {
err = nil
m.LabelName = labelName
_,err = o.Insert(m)
}else{
_,err = o.Update(m)
_, err = o.Insert(m)
} else {
_, err = o.Update(m)
}
return err
}
//批量插入或更新标签.
func (m *Label) InsertOrUpdateMulti(labels string) {
if labels != "" {
func (m *Label) InsertOrUpdateMulti(labels string) {
if labels != "" {
labelArray := strings.Split(labels, ",")
for _, label := range labelArray {
@@ -73,10 +74,10 @@ func (m *Label) InsertOrUpdateMulti(labels string) {
}
//分页查找标签.
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) {
o := orm.NewOrm()
count,err := o.QueryTable(m.TableNameWithPrefix()).Count()
count, err := o.QueryTable(m.TableNameWithPrefix()).Count()
if err != nil {
return
@@ -85,8 +86,7 @@ func (m *Label) FindToPager(pageIndex, pageSize int) (labels []*Label,totalCount
offset := (pageIndex - 1) * pageSize
_,err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-book_number").Offset(offset).Limit(pageSize).All(&labels)
_, err = o.QueryTable(m.TableNameWithPrefix()).OrderBy("-book_number").Offset(offset).Limit(pageSize).All(&labels)
return
}

View File

@@ -1,38 +1,39 @@
package models
import (
"time"
"errors"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"sync/atomic"
"github.com/astaxie/beego/orm"
"errors"
"time"
)
var loggerQueue = &logQueue{ channel : make(chan *Logger,100),isRuning : 0 }
var loggerQueue = &logQueue{channel: make(chan *Logger, 100), isRuning: 0}
type logQueue struct {
channel chan *Logger
channel chan *Logger
isRuning int32
}
// Logger struct .
type Logger struct {
LoggerId int64 `orm:"pk;auto;unique;column(log_id)" json:"log_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
LoggerId int64 `orm:"pk;auto;unique;column(log_id)" json:"log_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
// 日志类别operate 操作日志/ system 系统日志/ exception 异常日志 / document 文档操作日志
Category string `orm:"column(category);size(255);default(operate)" json:"category"`
Content string `orm:"column(content);type(text)" json:"content"`
OriginalData string `orm:"column(original_data);type(text)" json:"original_data"`
PresentData string `orm:"column(present_data);type(text)" json:"present_data"`
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add" json:"create_time"`
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
IPAddress string `orm:"column(ip_address);size(255)" json:"ip_address"`
Category string `orm:"column(category);size(255);default(operate)" json:"category"`
Content string `orm:"column(content);type(text)" json:"content"`
OriginalData string `orm:"column(original_data);type(text)" json:"original_data"`
PresentData string `orm:"column(present_data);type(text)" json:"present_data"`
CreateTime time.Time `orm:"type(datetime);column(create_time);auto_now_add" json:"create_time"`
UserAgent string `orm:"column(user_agent);size(500)" json:"user_agent"`
IPAddress string `orm:"column(ip_address);size(255)" json:"ip_address"`
}
// TableName 获取对应数据库表名.
func (m *Logger) TableName() string {
return "logs"
}
// TableEngine 获取数据使用的引擎.
func (m *Logger) TableEngine() string {
return "INNODB"
@@ -57,32 +58,19 @@ func (m *Logger) Add() error {
}
loggerQueue.channel <- m
if atomic.LoadInt32(&(loggerQueue.isRuning)) <= 0 {
atomic.AddInt32(&(loggerQueue.isRuning),1)
atomic.AddInt32(&(loggerQueue.isRuning), 1)
go addLoggerAsync()
}
return nil
}
func addLoggerAsync() {
defer atomic.AddInt32(&(loggerQueue.isRuning),-1)
func addLoggerAsync() {
defer atomic.AddInt32(&(loggerQueue.isRuning), -1)
o := orm.NewOrm()
for{
logger := <- loggerQueue.channel
for {
logger := <-loggerQueue.channel
o.Insert(logger)
}
}

View File

@@ -15,6 +15,7 @@ import (
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"github.com/lifei6671/mindoc/utils"
"math"
)
type Member struct {
@@ -108,7 +109,7 @@ func (m *Member) ldapLogin(account string, password string) (*Member, error) {
beego.AppConfig.String("ldap_base"),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
//修改objectClass通过配置文件获取值
fmt.Sprintf("(&(%s)(%s=%s))",beego.AppConfig.String("ldap_filter"), beego.AppConfig.String("ldap_attribute"), account),
fmt.Sprintf("(&(%s)(%s=%s))", beego.AppConfig.String("ldap_filter"), beego.AppConfig.String("ldap_attribute"), account),
[]string{"dn", "mail"},
nil,
)
@@ -279,7 +280,7 @@ func (m *Member) Valid(is_hash_password bool) error {
return ErrMemberEmailEmpty
}
//用户描述必须小于500字
if strings.Count(m.Description,"") > 500 {
if strings.Count(m.Description, "") > 500 {
return ErrMemberDescriptionTooLong
}
if m.Role != conf.MemberGeneralRole && m.Role != conf.MemberSuperRole && m.Role != conf.MemberAdminRole {
@@ -289,48 +290,47 @@ func (m *Member) Valid(is_hash_password bool) error {
m.Status = 0
}
//邮箱格式校验
if ok,err := regexp.MatchString(conf.RegexpEmail,m.Email); !ok || err != nil || m.Email == "" {
if ok, err := regexp.MatchString(conf.RegexpEmail, m.Email); !ok || err != nil || m.Email == "" {
return ErrMemberEmailFormatError
}
//如果是未加密密码,需要校验密码格式
if !is_hash_password {
if l := strings.Count(m.Password,"") ; m.Password == "" || l > 50 || l < 6{
if l := strings.Count(m.Password, ""); m.Password == "" || l > 50 || l < 6 {
return ErrMemberPasswordFormatError
}
}
//校验邮箱是否呗使用
if member,err := NewMember().FindByFieldFirst("email",m.Account); err == nil && member.MemberId > 0 {
if member, err := NewMember().FindByFieldFirst("email", m.Account); err == nil && member.MemberId > 0 {
if m.MemberId > 0 && m.MemberId != member.MemberId {
return ErrMemberEmailExist
}
if m.MemberId <= 0{
return ErrMemberEmailExist
if m.MemberId <= 0 {
return ErrMemberEmailExist
}
}
if m.MemberId > 0{
if m.MemberId > 0 {
//校验用户是否存在
if _,err := NewMember().Find(m.MemberId);err != nil {
if _, err := NewMember().Find(m.MemberId); err != nil {
return err
}
}else{
} else {
//校验账号格式是否正确
if ok,err := regexp.MatchString(conf.RegexpAccount,m.Account); m.Account == "" || !ok || err != nil {
if ok, err := regexp.MatchString(conf.RegexpAccount, m.Account); m.Account == "" || !ok || err != nil {
return ErrMemberAccountFormatError
}
//校验账号是否被使用
if member,err := NewMember().FindByAccount(m.Account); err == nil && member.MemberId > 0 {
if member, err := NewMember().FindByAccount(m.Account); err == nil && member.MemberId > 0 {
return ErrMemberExist
}
}
return nil
}
//删除一个用户.
func (m *Member) Delete(oldId int,newId int) error {
func (m *Member) Delete(oldId int, newId int) error {
o := orm.NewOrm()
err := o.Begin()
@@ -339,39 +339,39 @@ func (m *Member) Delete(oldId int,newId int) error {
return err
}
_,err = o.Raw("DELETE FROM md_members WHERE member_id = ?",oldId).Exec()
_, err = o.Raw("DELETE FROM md_members WHERE member_id = ?", oldId).Exec()
if err != nil {
o.Rollback()
return err
}
_,err = o.Raw("UPDATE md_attachment SET `create_at` = ? WHERE `create_at` = ?",newId,oldId).Exec()
_, err = o.Raw("UPDATE md_attachment SET `create_at` = ? WHERE `create_at` = ?", newId, oldId).Exec()
if err != nil {
o.Rollback()
return err
}
_,err = o.Raw("UPDATE md_books SET member_id = ? WHERE member_id = ?",newId,oldId).Exec()
_, err = o.Raw("UPDATE md_books SET member_id = ? WHERE member_id = ?", newId, oldId).Exec()
if err != nil {
o.Rollback()
return err
}
_,err = o.Raw("UPDATE md_document_history SET member_id=? WHERE member_id = ?",newId,oldId).Exec()
_, err = o.Raw("UPDATE md_document_history SET member_id=? WHERE member_id = ?", newId, oldId).Exec()
if err != nil {
o.Rollback()
return err
}
_,err = o.Raw("UPDATE md_document_history SET modify_at=? WHERE modify_at = ?",newId,oldId).Exec()
_, err = o.Raw("UPDATE md_document_history SET modify_at=? WHERE modify_at = ?", newId, oldId).Exec()
if err != nil {
o.Rollback()
return err
}
_,err = o.Raw("UPDATE md_documents SET member_id = ? WHERE member_id = ?;",newId,oldId).Exec()
_, err = o.Raw("UPDATE md_documents SET member_id = ? WHERE member_id = ?;", newId, oldId).Exec()
if err != nil {
o.Rollback()
return err
}
_,err = o.Raw("UPDATE md_documents SET modify_at = ? WHERE modify_at = ?",newId,oldId).Exec()
_, err = o.Raw("UPDATE md_documents SET modify_at = ? WHERE modify_at = ?", newId, oldId).Exec()
if err != nil {
o.Rollback()
return err
@@ -386,53 +386,37 @@ func (m *Member) Delete(oldId int,newId int) error {
//}
var relationship_list []*Relationship
_,err = o.QueryTable(NewRelationship().TableNameWithPrefix()).Filter("member_id",oldId).All(&relationship_list)
_, err = o.QueryTable(NewRelationship().TableNameWithPrefix()).Filter("member_id", oldId).Limit(math.MaxInt32).All(&relationship_list)
if err == nil {
for _,relationship := range relationship_list {
for _, relationship := range relationship_list {
//如果存在创始人,则删除
if relationship.RoleId == 0 {
rel := NewRelationship()
err = o.QueryTable(relationship.TableNameWithPrefix()).Filter("book_id",relationship.BookId).Filter("member_id",newId).One(rel)
err = o.QueryTable(relationship.TableNameWithPrefix()).Filter("book_id", relationship.BookId).Filter("member_id", newId).One(rel)
if err == nil {
if _,err := o.Delete(relationship) ; err != nil{
if _, err := o.Delete(relationship); err != nil {
beego.Error(err)
}
relationship.RelationshipId = rel.RelationshipId
}
relationship.MemberId = newId
relationship.RoleId = 0
if _,err := o.Update(relationship) ; err != nil{
if _, err := o.Update(relationship); err != nil {
beego.Error(err)
}
}else{
if _,err := o.Delete(relationship) ; err != nil{
} else {
if _, err := o.Delete(relationship); err != nil {
beego.Error(err)
}
}
}
}
if err = o.Commit();err != nil {
if err = o.Commit(); err != nil {
o.Rollback()
return err
}
return nil
}

View File

@@ -1,27 +1,27 @@
package models
import (
"time"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
)
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"`
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"`
RoleName string `json:"role_name"`
RoleId int `json:"role_id"`
RoleName string `json:"role_name"`
}
func NewMemberRelationshipResult() *MemberRelationshipResult {
@@ -43,18 +43,18 @@ func (m *MemberRelationshipResult) FromMember(member *Member) *MemberRelationshi
return m
}
func (m *MemberRelationshipResult) ResolveRoleName () *MemberRelationshipResult {
func (m *MemberRelationshipResult) ResolveRoleName() *MemberRelationshipResult {
if m.RoleId == conf.BookAdmin {
m.RoleName = "管理者"
}else if m.RoleId == conf.BookEditor {
} else if m.RoleId == conf.BookEditor {
m.RoleName = "编辑者"
}else if m.RoleId == conf.BookObserver {
} else if m.RoleId == conf.BookObserver {
m.RoleName = "观察者"
}
return m
}
func (m *MemberRelationshipResult) FindForUsersByBookId(book_id ,pageIndex, pageSize int) ([]*MemberRelationshipResult,int,error) {
func (m *MemberRelationshipResult) FindForUsersByBookId(book_id, pageIndex, pageSize int) ([]*MemberRelationshipResult, int, error) {
o := orm.NewOrm()
var members []*MemberRelationshipResult
@@ -65,28 +65,22 @@ func (m *MemberRelationshipResult) FindForUsersByBookId(book_id ,pageIndex, page
var total_count int
err := o.Raw(sql2,book_id).QueryRow(&total_count)
err := o.Raw(sql2, book_id).QueryRow(&total_count)
if err != nil {
return members,0,err
return members, 0, err
}
offset := (pageIndex-1) * pageSize
offset := (pageIndex - 1) * pageSize
_,err = o.Raw(sql1,book_id,offset,pageSize).QueryRows(&members)
_, err = o.Raw(sql1, book_id, offset, pageSize).QueryRows(&members)
if err != nil {
return members,0,err
return members, 0, err
}
for _,item := range members {
for _, item := range members {
item.ResolveRoleName()
}
return members,total_count,nil
return members, total_count, nil
}

View File

@@ -1,66 +1,66 @@
package models
import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
)
type MemberToken struct {
TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
Token string `orm:"column(token);size(150);index" json:"token"`
Email string `orm:"column(email);size(255)" json:"email"`
IsValid bool `orm:"column(is_valid)" json:"is_valid"`
ValidTime time.Time `orm:"column(valid_time);null" json:"valid_time"`
SendTime time.Time `orm:"column(send_time);auto_now_add;type(datetime)" json:"send_time"`
TokenId int `orm:"column(token_id);pk;auto;unique" json:"token_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
Token string `orm:"column(token);size(150);index" json:"token"`
Email string `orm:"column(email);size(255)" json:"email"`
IsValid bool `orm:"column(is_valid)" json:"is_valid"`
ValidTime time.Time `orm:"column(valid_time);null" json:"valid_time"`
SendTime time.Time `orm:"column(send_time);auto_now_add;type(datetime)" json:"send_time"`
}
// TableName 获取对应数据库表名.
func (m *MemberToken) TableName() string {
return "member_token"
}
// TableEngine 获取数据使用的引擎.
func (m *MemberToken) TableEngine() string {
return "INNODB"
}
func (m *MemberToken)TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
func (m *MemberToken) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
}
func NewMemberToken() *MemberToken {
return &MemberToken{}
}
func (m *MemberToken) InsertOrUpdate() (*MemberToken,error){
func (m *MemberToken) InsertOrUpdate() (*MemberToken, error) {
o := orm.NewOrm()
if m.TokenId > 0 {
_,err := o.Update(m)
return m,err
_, err := o.Update(m)
return m, err
}
_,err := o.Insert(m)
_, err := o.Insert(m)
return m,err
return m, err
}
func (m *MemberToken) FindByFieldFirst(field string,value interface{}) (*MemberToken,error) {
func (m *MemberToken) FindByFieldFirst(field string, value interface{}) (*MemberToken, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter(field,value).OrderBy("-token_id").One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter(field, value).OrderBy("-token_id").One(m)
return m,err
return m, err
}
func (m *MemberToken) FindSendCount(mail string,start_time time.Time,end_time time.Time) (int ,error) {
func (m *MemberToken) FindSendCount(mail string, start_time time.Time, end_time time.Time) (int, error) {
o := orm.NewOrm()
c,err := o.QueryTable(m.TableNameWithPrefix()).Filter("send_time__gte",start_time.Format("2006-01-02 15:04:05")).Filter("send_time__lte",end_time.Format("2006-01-02 15:04:05")).Count()
c, err := o.QueryTable(m.TableNameWithPrefix()).Filter("send_time__gte", start_time.Format("2006-01-02 15:04:05")).Filter("send_time__lte", end_time.Format("2006-01-02 15:04:05")).Count()
if err != nil {
return 0,err
return 0, err
}
return int(c),nil
}
return int(c), nil
}

View File

@@ -1,18 +1,18 @@
package models
import (
"time"
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
"time"
)
type Migration struct {
MigrationId int `orm:"column(migration_id);pk;auto;unique;" json:"migration_id"`
Name string `orm:"column(name);size(500)" json:"name"`
Statements string `orm:"column(statements);type(text);null" json:"statements"`
Status string `orm:"column(status);default(update)" json:"status"`
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
Version int64 `orm:"type(bigint);column(version);unique" json:"version"`
MigrationId int `orm:"column(migration_id);pk;auto;unique;" json:"migration_id"`
Name string `orm:"column(name);size(500)" json:"name"`
Statements string `orm:"column(statements);type(text);null" json:"statements"`
Status string `orm:"column(status);default(update)" json:"status"`
CreateTime time.Time `orm:"column(create_time);type(datetime);auto_now_add" json:"create_time"`
Version int64 `orm:"type(bigint);column(version);unique" json:"version"`
}
// TableName 获取对应数据库表名.
@@ -33,10 +33,10 @@ func NewMigration() *Migration {
return &Migration{}
}
func (m *Migration) FindFirst() (*Migration,error) {
func (m *Migration) FindFirst() (*Migration, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).OrderBy("-migration_id").One(m)
return m,err
}
return m, err
}

View File

@@ -5,147 +5,145 @@ import (
"github.com/lifei6671/mindoc/conf"
)
// Option struct .
type Option struct {
OptionId int `orm:"column(option_id);pk;auto;unique;" json:"option_id"`
OptionTitle string `orm:"column(option_title);size(500)" json:"option_title"`
OptionName string `orm:"column(option_name);unique;size(80)" json:"option_name"`
OptionValue string `orm:"column(option_value);type(text);null" json:"option_value"`
Remark string `orm:"column(remark);type(text);null" json:"remark"`
OptionId int `orm:"column(option_id);pk;auto;unique;" json:"option_id"`
OptionTitle string `orm:"column(option_title);size(500)" json:"option_title"`
OptionName string `orm:"column(option_name);unique;size(80)" json:"option_name"`
OptionValue string `orm:"column(option_value);type(text);null" json:"option_value"`
Remark string `orm:"column(remark);type(text);null" json:"remark"`
}
// TableName 获取对应数据库表名.
func (m *Option) TableName() string {
return "options"
}
// TableEngine 获取数据使用的引擎.
func (m *Option) TableEngine() string {
return "INNODB"
}
func (m *Option)TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
func (m *Option) TableNameWithPrefix() string {
return conf.GetDatabasePrefix() + m.TableName()
}
func NewOption() *Option {
func NewOption() *Option {
return &Option{}
}
func (p *Option) Find(id int) (*Option,error) {
func (p *Option) Find(id int) (*Option, error) {
o := orm.NewOrm()
p.OptionId = id
if err := o.Read(p);err != nil {
return p,err
if err := o.Read(p); err != nil {
return p, err
}
return p,nil
return p, nil
}
func (p *Option) FindByKey(key string) (*Option,error) {
func (p *Option) FindByKey(key string) (*Option, error) {
o := orm.NewOrm()
p.OptionName = key
if err := o.Read(p);err != nil {
return p,err
if err := o.Read(p); err != nil {
return p, err
}
return p,nil
return p, nil
}
func GetOptionValue(key, def string) string {
if option,err := NewOption().FindByKey(key); err == nil {
if option, err := NewOption().FindByKey(key); err == nil {
return option.OptionValue
}
return def
}
func (p *Option) InsertOrUpdate() error {
func (p *Option) InsertOrUpdate() error {
o := orm.NewOrm()
var err error
if p.OptionId > 0 || o.QueryTable(p.TableNameWithPrefix()).Filter("option_name",p.OptionName).Exist() {
_,err = o.Update(p)
}else{
_,err = o.Insert(p)
if p.OptionId > 0 || o.QueryTable(p.TableNameWithPrefix()).Filter("option_name", p.OptionName).Exist() {
_, err = o.Update(p)
} else {
_, err = o.Insert(p)
}
return err
}
func (p *Option) InsertMulti(option... Option ) (error){
func (p *Option) InsertMulti(option ...Option) error {
o := orm.NewOrm()
_,err := o.InsertMulti(len(option),option)
_, err := o.InsertMulti(len(option), option)
return err
}
func (p *Option) All() ([]*Option,error) {
func (p *Option) All() ([]*Option, error) {
o := orm.NewOrm()
var options []*Option
_,err := o.QueryTable(p.TableNameWithPrefix()).All(&options)
_, err := o.QueryTable(p.TableNameWithPrefix()).All(&options)
if err != nil {
return options,err
return options, err
}
return options,nil
return options, nil
}
func (m *Option) Init() error {
o := orm.NewOrm()
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLED_REGISTER").Exist() {
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLED_REGISTER").Exist() {
option := NewOption()
option.OptionValue = "false"
option.OptionName = "ENABLED_REGISTER"
option.OptionTitle = "是否启用注册"
if _,err := o.Insert(option);err != nil {
if _, err := o.Insert(option); err != nil {
return err
}
}
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLE_DOCUMENT_HISTORY").Exist() {
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLE_DOCUMENT_HISTORY").Exist() {
option := NewOption()
option.OptionValue = "true"
option.OptionName = "ENABLE_DOCUMENT_HISTORY"
option.OptionTitle = "是否启用文档历史"
if _,err := o.Insert(option);err != nil {
if _, err := o.Insert(option); err != nil {
return err
}
}
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLED_CAPTCHA").Exist() {
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLED_CAPTCHA").Exist() {
option := NewOption()
option.OptionValue = "true"
option.OptionName = "ENABLED_CAPTCHA"
option.OptionTitle = "是否启用验证码"
if _,err := o.Insert(option);err != nil {
if _, err := o.Insert(option); err != nil {
return err
}
}
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","ENABLE_ANONYMOUS").Exist() {
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "ENABLE_ANONYMOUS").Exist() {
option := NewOption()
option.OptionValue = "false"
option.OptionName = "ENABLE_ANONYMOUS"
option.OptionTitle = "启用匿名访问"
if _,err := o.Insert(option);err != nil {
if _, err := o.Insert(option); err != nil {
return err
}
}
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name","SITE_NAME").Exist() {
if !o.QueryTable(m.TableNameWithPrefix()).Filter("option_name", "SITE_NAME").Exist() {
option := NewOption()
option.OptionValue = "MinDoc"
option.OptionName = "SITE_NAME"
option.OptionTitle = "站点名称"
if _,err := o.Insert(option);err != nil {
if _, err := o.Insert(option); err != nil {
return err
}
}
return nil
}
}

View File

@@ -1,21 +1,20 @@
package models
import (
"github.com/lifei6671/mindoc/conf"
"github.com/astaxie/beego/orm"
"errors"
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"github.com/lifei6671/mindoc/conf"
)
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"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
RelationshipId int `orm:"pk;auto;unique;column(relationship_id)" json:"relationship_id"`
MemberId int `orm:"column(member_id);type(int)" json:"member_id"`
BookId int `orm:"column(book_id);type(int)" json:"book_id"`
// RoleId 角色0 创始人(创始人不能被移除) / 1 管理员/2 编辑者/3 观察者
RoleId int `orm:"column(role_id);type(int)" json:"role_id"`
RoleId int `orm:"column(role_id);type(int)" json:"role_id"`
}
// TableName 获取对应数据库表名.
func (m *Relationship) TableName() string {
return "relationship"
@@ -40,97 +39,97 @@ func NewRelationship() *Relationship {
return &Relationship{}
}
func (m *Relationship) Find(id int) (*Relationship,error) {
func (m *Relationship) Find(id int) (*Relationship, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("relationship_id",id).One(m)
return m,err
err := o.QueryTable(m.TableNameWithPrefix()).Filter("relationship_id", id).One(m)
return m, err
}
//查询指定项目的创始人.
func (m *Relationship) FindFounder(book_id int) (*Relationship,error) {
func (m *Relationship) FindFounder(book_id int) (*Relationship, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("role_id",0).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("role_id", 0).One(m)
return m,err
return m, err
}
func (m *Relationship) UpdateRoleId(book_id,member_id, role_id int) (*Relationship,error) {
func (m *Relationship) UpdateRoleId(book_id, member_id, role_id int) (*Relationship, error) {
o := orm.NewOrm()
book := NewBook()
book.BookId = book_id
if err := o.Read(book); err != nil {
logs.Error("UpdateRoleId => ", err)
return m,errors.New("项目不存在")
return m, errors.New("项目不存在")
}
err := o.QueryTable(m.TableNameWithPrefix()).Filter("member_id",member_id).Filter("book_id",book_id).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("member_id", member_id).Filter("book_id", book_id).One(m)
if err == orm.ErrNoRows {
m = NewRelationship()
m.BookId = book_id
m.MemberId = member_id
m.RoleId = role_id
}else if err != nil {
return m,err
}else if m.RoleId == conf.BookFounder{
return m,errors.New("不能变更创始人的权限")
} else if err != nil {
return m, err
} else if m.RoleId == conf.BookFounder {
return m, errors.New("不能变更创始人的权限")
}
m.RoleId = role_id
if m.RelationshipId > 0 {
_,err = o.Update(m)
}else{
_,err = o.Insert(m)
_, err = o.Update(m)
} else {
_, err = o.Insert(m)
}
return m,err
return m, err
}
func (m *Relationship) FindForRoleId(book_id ,member_id int) (int,error) {
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)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", member_id).One(relationship)
if err != nil {
return 0,err
return 0, err
}
return relationship.RoleId,nil
return relationship.RoleId, nil
}
func (m *Relationship) FindByBookIdAndMemberId(book_id ,member_id int) (*Relationship,error) {
func (m *Relationship) FindByBookIdAndMemberId(book_id, member_id int) (*Relationship, error) {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",member_id).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", member_id).One(m)
return m,err
return m, err
}
func (m *Relationship) Insert() error {
func (m *Relationship) Insert() error {
o := orm.NewOrm()
_,err := o.Insert(m)
_, err := o.Insert(m)
return err
}
func (m *Relationship) Update() error {
func (m *Relationship) Update() error {
o := orm.NewOrm()
_,err := o.Update(m)
_, err := o.Update(m)
return err
}
func (m *Relationship) DeleteByBookIdAndMemberId(book_id,member_id int) error {
func (m *Relationship) DeleteByBookIdAndMemberId(book_id, member_id int) error {
o := orm.NewOrm()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",member_id).One(m)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", member_id).One(m)
if err == orm.ErrNoRows {
return errors.New("用户未参与该项目")
@@ -138,22 +137,22 @@ func (m *Relationship) DeleteByBookIdAndMemberId(book_id,member_id int) error {
if m.RoleId == conf.BookFounder {
return errors.New("不能删除创始人")
}
_,err = o.Delete(m)
_, err = o.Delete(m)
if err != nil {
logs.Error("删除项目参与者 => ",err)
logs.Error("删除项目参与者 => ", err)
return errors.New("删除失败")
}
return nil
}
func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
func (m *Relationship) Transfer(book_id, founder_id, receive_id int) error {
o := orm.NewOrm()
founder := NewRelationship()
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",founder_id).One(founder)
err := o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", founder_id).One(founder)
if err != nil {
return err
@@ -163,7 +162,7 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
}
receive := NewRelationship()
err = o.QueryTable(m.TableNameWithPrefix()).Filter("book_id",book_id).Filter("member_id",receive_id).One(receive)
err = o.QueryTable(m.TableNameWithPrefix()).Filter("book_id", book_id).Filter("member_id", receive_id).One(receive)
if err != orm.ErrNoRows && err != nil {
return err
@@ -176,17 +175,17 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
receive.RoleId = conf.BookFounder
receive.BookId = book_id
if err := founder.Update();err != nil {
if err := founder.Update(); err != nil {
o.Rollback()
return err
}
if receive.RelationshipId > 0 {
if _,err := o.Update(receive);err != nil {
if _, err := o.Update(receive); err != nil {
o.Rollback()
return err
}
}else{
if _,err := o.Insert(receive);err != nil {
} else {
if _, err := o.Insert(receive); err != nil {
o.Rollback()
return err
}
@@ -194,24 +193,3 @@ func (m *Relationship) Transfer(book_id,founder_id,receive_id int) error {
return o.Commit()
}