attachment feature #10
This commit is contained in:
212
app/controllers/AttachController.go
Normal file
212
app/controllers/AttachController.go
Normal file
@ -0,0 +1,212 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
// "encoding/json"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"io"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
)
|
||||
|
||||
// 附件
|
||||
type Attach struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// 上传附件
|
||||
func (c Attach) UploadAttach(noteId string) revel.Result {
|
||||
re := c.uploadAttach(noteId)
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
func (c Attach) uploadAttach(noteId string) (re info.Re) {
|
||||
var fileId = ""
|
||||
var resultMsg = "error" // 错误信息
|
||||
var Ok = false
|
||||
var fileInfo info.Attach
|
||||
|
||||
re = info.NewRe()
|
||||
|
||||
defer func() {
|
||||
re.Id = fileId // 只是id, 没有其它信息
|
||||
re.Msg = resultMsg
|
||||
re.Ok = Ok
|
||||
re.Item = fileInfo
|
||||
}()
|
||||
|
||||
// 判断是否有权限为笔记添加附件
|
||||
if !shareService.HasUpdateNotePerm(noteId, c.GetUserId()) {
|
||||
return re
|
||||
}
|
||||
|
||||
file, handel, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
// > 5M?
|
||||
if(len(data) > 5 * 1024 * 1024) {
|
||||
resultMsg = "File is bigger than 5M"
|
||||
return re
|
||||
}
|
||||
|
||||
// 生成上传路径
|
||||
filePath := "files/" + c.GetUserId() + "/attachs"
|
||||
dir := revel.BasePath + "/" + filePath
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
// 生成新的文件名
|
||||
filename := handel.Filename
|
||||
_, ext := SplitFilename(filename) // .doc
|
||||
filename = NewGuid() + ext
|
||||
toPath := dir + "/" + filename;
|
||||
err = ioutil.WriteFile(toPath, data, 0777)
|
||||
if err != nil {
|
||||
return re
|
||||
}
|
||||
|
||||
// add File to db
|
||||
fileType := ""
|
||||
if ext != "" {
|
||||
fileType = strings.ToLower(ext[1:])
|
||||
}
|
||||
filesize := GetFilesize(toPath)
|
||||
fileInfo = info.Attach{Name: filename,
|
||||
Title: handel.Filename,
|
||||
NoteId: bson.ObjectIdHex(noteId),
|
||||
UploadUserId: c.GetObjectUserId(),
|
||||
Path: filePath + "/" + filename,
|
||||
Type: fileType,
|
||||
Size: filesize}
|
||||
|
||||
id := bson.NewObjectId();
|
||||
fileInfo.AttachId = id
|
||||
fileId = id.Hex()
|
||||
Ok = attachService.AddAttach(fileInfo)
|
||||
|
||||
fileInfo.Path = ""; // 不要返回
|
||||
resultMsg = "success"
|
||||
|
||||
return re
|
||||
}
|
||||
|
||||
// 删除附件
|
||||
func (c Attach) DeleteAttach(attachId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok, re.Msg = attachService.DeleteAttach(attachId, c.GetUserId())
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// get all attachs by noteId
|
||||
func (c Attach) GetAttachs(noteId string) revel.Result {
|
||||
re := info.NewRe()
|
||||
re.Ok = true
|
||||
re.List = attachService.ListAttachs(noteId, c.GetUserId())
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 下载附件
|
||||
// 权限判断
|
||||
func (c Attach) Download(attachId string) revel.Result {
|
||||
attach := attachService.GetAttach(attachId, c.GetUserId()); // 得到路径
|
||||
path := attach.Path
|
||||
if path == "" {
|
||||
return c.RenderText("")
|
||||
}
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(path, "/")
|
||||
file, _ := os.Open(fn)
|
||||
return c.RenderBinary(file, attach.Title, revel.Attachment, time.Now()) // revel.Attachment
|
||||
// return c.RenderFile(file, revel.Attachment) // revel.Attachment
|
||||
}
|
||||
|
||||
func (c Attach) DownloadAll(noteId string) revel.Result {
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.NoteId == "" {
|
||||
return c.RenderText("")
|
||||
}
|
||||
// 得到文件列表
|
||||
attachs := attachService.ListAttachs(noteId, c.GetUserId())
|
||||
if attachs == nil || len(attachs) == 0 {
|
||||
return c.RenderText("")
|
||||
}
|
||||
|
||||
/*
|
||||
dir := revel.BasePath + "/files/tmp"
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
*/
|
||||
|
||||
filename := note.Title + ".tar.gz"
|
||||
if note.Title == "" {
|
||||
filename = "all.tar.gz"
|
||||
}
|
||||
|
||||
// file write
|
||||
fw, err := os.Create(revel.BasePath + "/files/" + filename)
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
// defer fw.Close() // 不需要关闭, 还要读取给用户下载
|
||||
|
||||
// gzip write
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// tar write
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// 遍历文件列表
|
||||
for _, attach := range attachs {
|
||||
fn := revel.BasePath + "/" + strings.TrimLeft(attach.Path, "/")
|
||||
fr, err := os.Open(fn)
|
||||
fileInfo, _ := fr.Stat()
|
||||
if err != nil {
|
||||
return c.RenderText("")
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// 信息头
|
||||
h := new(tar.Header)
|
||||
h.Name = attach.Title
|
||||
h.Size = fileInfo.Size()
|
||||
h.Mode = int64(fileInfo.Mode())
|
||||
h.ModTime = fileInfo.ModTime()
|
||||
|
||||
// 写信息头
|
||||
err = tw.WriteHeader(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 写文件
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} // for
|
||||
|
||||
// tw.Close()
|
||||
// gw.Close()
|
||||
// fw.Close()
|
||||
// file, _ := os.Open(dir + "/" + filename)
|
||||
// fw.Seek(0, 0)
|
||||
return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachment
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ type File struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// 上传图片 editor
|
||||
// 过时 已弃用!
|
||||
func (c File) UploadImage(renderHtml string) revel.Result {
|
||||
if renderHtml == "" {
|
||||
@ -33,18 +32,19 @@ func (c File) UploadImage(renderHtml string) revel.Result {
|
||||
return c.RenderTemplate(renderHtml)
|
||||
}
|
||||
|
||||
// 已弃用
|
||||
func (c File) UploadImageJson(from, noteId string) revel.Result {
|
||||
re := c.uploadImage(from, "");
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
|
||||
// 上传的是博客logo
|
||||
// TODO logo不要设置权限, 另外的目录
|
||||
func (c File) UploadBlogLogo() revel.Result {
|
||||
return c.UploadImage("file/blog_logo.html");
|
||||
}
|
||||
|
||||
// 弃用
|
||||
func (c File) UploadImageJson(from, noteId string) revel.Result {
|
||||
re := c.uploadImage(from, "");
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 拖拉上传, pasteImage
|
||||
// noteId 是为了判断是否是协作的note, 如果是则需要复制一份到note owner中
|
||||
func (c File) PasteImage(noteId string) revel.Result {
|
||||
@ -69,13 +69,14 @@ func (c File) PasteImage(noteId string) revel.Result {
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// leaui image plugin
|
||||
// leaui image plugin upload image
|
||||
func (c File) UploadImageLeaui(albumId string) revel.Result {
|
||||
re := c.uploadImage("", albumId);
|
||||
return c.RenderJson(re)
|
||||
}
|
||||
|
||||
// 上传图片, 公用方法
|
||||
// upload image common func
|
||||
func (c File) uploadImage(from, albumId string) (re info.Re) {
|
||||
var fileUrlPath = ""
|
||||
var fileId = ""
|
||||
|
@ -25,6 +25,7 @@ var suggestionService *service.SuggestionService
|
||||
|
||||
var albumService *service.AlbumService
|
||||
var fileService *service.FileService
|
||||
var attachService *service.AttachService
|
||||
|
||||
var pageSize = 1000
|
||||
var defaultSortField = "UpdatedTime"
|
||||
|
@ -36,6 +36,7 @@ var Suggestions *mgo.Collection
|
||||
// Album & file(image)
|
||||
var Albums *mgo.Collection
|
||||
var Files *mgo.Collection
|
||||
var Attachs *mgo.Collection
|
||||
|
||||
var NoteImages *mgo.Collection
|
||||
|
||||
@ -106,6 +107,7 @@ func Init() {
|
||||
// Album & file
|
||||
Albums = Session.DB(dbname).C("albums")
|
||||
Files = Session.DB(dbname).C("files")
|
||||
Attachs = Session.DB(dbname).C("attachs")
|
||||
|
||||
NoteImages = Session.DB(dbname).C("note_images")
|
||||
}
|
||||
|
21
app/info/AttachInfo.go
Normal file
21
app/info/AttachInfo.go
Normal file
@ -0,0 +1,21 @@
|
||||
package info
|
||||
|
||||
import (
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Attach belongs to note
|
||||
type Attach struct {
|
||||
AttachId bson.ObjectId `bson:"_id,omitempty"` //
|
||||
NoteId bson.ObjectId `bson:"NoteId"` //
|
||||
UploadUserId bson.ObjectId `bson:"UploadUserId"` // 可以不是note owner, 协作者userId
|
||||
Name string `Name` // file name, md5, such as 13232312.doc
|
||||
Title string `Title` // raw file name
|
||||
Size int64 `Size` // file size (byte)
|
||||
Type string `Type` // file type, "doc" = word
|
||||
Path string `Path` // the file path such as: files/userId/attachs/adfadf.doc
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
|
||||
// FromFileId bson.ObjectId `bson:"FromFileId,omitempty"` // copy from fileId, for collaboration
|
||||
}
|
@ -24,7 +24,7 @@ type Note struct {
|
||||
|
||||
IsMarkdown bool `IsMarkdown` // 是否是markdown笔记, 默认是false
|
||||
|
||||
AttachIds []string `FileIds,omitempty` // 2014/9/18, attachments
|
||||
AttachNum int `AttachNum` // 2014/9/21, attachments num
|
||||
|
||||
CreatedTime time.Time `CreatedTime`
|
||||
UpdatedTime time.Time `UpdatedTime`
|
||||
|
175
app/service/AttachService.go
Normal file
175
app/service/AttachService.go
Normal file
@ -0,0 +1,175 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AttachService struct {
|
||||
}
|
||||
|
||||
// add attach
|
||||
func (this *AttachService) AddAttach(attach info.Attach) bool {
|
||||
attach.CreatedTime = time.Now()
|
||||
ok := db.Insert(db.Attachs, attach)
|
||||
|
||||
if ok {
|
||||
// 更新笔记的attachs num
|
||||
this.updateNoteAttachNum(attach.NoteId, 1)
|
||||
}
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
// 更新笔记的附件个数
|
||||
// addNum 1或-1
|
||||
func (this *AttachService) updateNoteAttachNum(noteId bson.ObjectId, addNum int) bool {
|
||||
num := db.Count(db.Attachs, bson.M{"NoteId": noteId})
|
||||
/*
|
||||
note := info.Note{}
|
||||
note = noteService.GetNoteById(noteId.Hex())
|
||||
note.AttachNum += addNum
|
||||
if note.AttachNum < 0 {
|
||||
note.AttachNum = 0
|
||||
}
|
||||
Log(note.AttachNum)
|
||||
*/
|
||||
return db.UpdateByQField(db.Notes, bson.M{"_id": noteId}, "AttachNum", num)
|
||||
}
|
||||
|
||||
// list attachs
|
||||
func (this *AttachService) ListAttachs(noteId, userId string) []info.Attach {
|
||||
attachs := []info.Attach{}
|
||||
// 判断是否有权限为笔记添加附件
|
||||
if !shareService.HasUpdateNotePerm(noteId, userId) {
|
||||
return attachs
|
||||
}
|
||||
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.ObjectIdHex(noteId)}, &attachs)
|
||||
|
||||
return attachs
|
||||
}
|
||||
|
||||
func (this *AttachService) UpdateImageTitle(userId, fileId, title string) bool {
|
||||
return db.UpdateByIdAndUserIdField(db.Files, fileId, userId, "Title", title)
|
||||
}
|
||||
|
||||
|
||||
// Delete note to delete attas firstly
|
||||
func (this *AttachService) DeleteAllAttachs(noteId, userId string) bool {
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.UserId.Hex() == userId {
|
||||
attachs := []info.Attach{}
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.ObjectIdHex(noteId)}, &attachs)
|
||||
for _, attach := range attachs {
|
||||
attach.Path = strings.TrimLeft(attach.Path, "/")
|
||||
os.Remove(revel.BasePath + "/" + attach.Path)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// delete attach
|
||||
func (this *AttachService) DeleteAttach(attachId, userId string) (bool, string) {
|
||||
attach := info.Attach{}
|
||||
db.Get(db.Attachs, attachId, &attach)
|
||||
|
||||
if(attach.AttachId != "") {
|
||||
// 判断是否有权限为笔记添加附件
|
||||
if !shareService.HasUpdateNotePerm(attach.NoteId.Hex(), userId) {
|
||||
return false, "No Perm"
|
||||
}
|
||||
|
||||
if db.Delete(db.Attachs, bson.M{"_id": bson.ObjectIdHex(attachId)}) {
|
||||
this.updateNoteAttachNum(attach.NoteId, -1)
|
||||
attach.Path = strings.TrimLeft(attach.Path, "/")
|
||||
err := os.Remove(revel.BasePath + "/" + attach.Path)
|
||||
if err == nil {
|
||||
return true, "delete file error"
|
||||
}
|
||||
return false, "delete file error"
|
||||
}
|
||||
return false, "db error"
|
||||
}
|
||||
return false, "no such item"
|
||||
}
|
||||
|
||||
// 获取文件路径
|
||||
// 要判断是否具有权限
|
||||
// userId是否具有attach的访问权限
|
||||
func (this *AttachService) GetAttach(attachId, userId string) (attach info.Attach) {
|
||||
if attachId == "" {
|
||||
return
|
||||
}
|
||||
|
||||
attach = info.Attach{}
|
||||
db.Get(db.Attachs, attachId, &attach)
|
||||
path := attach.Path
|
||||
if path == "" {
|
||||
return
|
||||
}
|
||||
|
||||
note := noteService.GetNoteById(attach.NoteId.Hex())
|
||||
|
||||
// 判断权限
|
||||
|
||||
// 笔记是否是公开的
|
||||
if note.IsBlog {
|
||||
return
|
||||
}
|
||||
|
||||
// 笔记是否是我的
|
||||
if note.UserId.Hex() == userId {
|
||||
return
|
||||
}
|
||||
|
||||
// 我是否有权限查看或协作
|
||||
if shareService.HasReadNotePerm(attach.NoteId.Hex(), userId) {
|
||||
return
|
||||
}
|
||||
|
||||
attach = info.Attach{}
|
||||
return
|
||||
}
|
||||
|
||||
// 复制笔记时需要复制附件
|
||||
// noteService调用, 权限已判断
|
||||
func (this *AttachService) CopyAttachs(noteId, toNoteId, toUserId string) bool {
|
||||
attachs := []info.Attach{}
|
||||
db.ListByQ(db.Attachs, bson.M{"NoteId": bson.ObjectIdHex(noteId)}, &attachs)
|
||||
|
||||
// 复制之
|
||||
toNoteIdO := bson.ObjectIdHex(toNoteId)
|
||||
for _, attach := range attachs {
|
||||
attach.AttachId = ""
|
||||
attach.NoteId = toNoteIdO
|
||||
|
||||
// 文件复制一份
|
||||
_, ext := SplitFilename(attach.Name)
|
||||
newFilename := NewGuid() + ext
|
||||
dir := "files/" + toUserId + "/attachs"
|
||||
filePath := dir + "/" + newFilename
|
||||
err := os.MkdirAll(revel.BasePath + "/" + dir, 0755)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_, err = CopyFile(revel.BasePath + "/" + attach.Path, revel.BasePath + "/" + filePath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
attach.Name = newFilename
|
||||
attach.Path = filePath
|
||||
|
||||
this.AddAttach(attach)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
@ -189,7 +189,6 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin
|
||||
if file.FileId == "" || file.UserId.Hex() != userId {
|
||||
return false, ""
|
||||
}
|
||||
Log(file)
|
||||
|
||||
_, ext := SplitFilename(file.Name)
|
||||
newFilename := NewGuid() + ext
|
||||
|
@ -366,6 +366,9 @@ func (this *NoteService) CopySharedNote(noteId, notebookId, fromUserId, myUserId
|
||||
// 复制图片, 把note的图片都copy给我, 且修改noteContent图片路径
|
||||
noteContent.Content = noteImageService.CopyNoteImages(noteId, fromUserId, note.NoteId.Hex(), noteContent.Content, myUserId)
|
||||
|
||||
// 复制附件
|
||||
attachService.CopyAttachs(noteId, note.NoteId.Hex(), myUserId)
|
||||
|
||||
// 添加之
|
||||
note = this.AddNoteAndContent(note, noteContent, note.UserId);
|
||||
|
||||
|
@ -3,7 +3,7 @@ package service
|
||||
import (
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"sort"
|
||||
@ -286,6 +286,28 @@ func (this *ShareService) AddShareNote(noteId string, perm int, userId, email st
|
||||
return db.Insert(db.ShareNotes, shareNote), "", toUserId
|
||||
}
|
||||
|
||||
// updatedUserId是否有查看userId noteId的权限?
|
||||
func (this *ShareService) HasReadPerm(userId, updatedUserId, noteId string) bool {
|
||||
if !db.Has(db.ShareNotes,
|
||||
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NoteId": bson.ObjectIdHex(noteId)}) {
|
||||
// noteId的notebookId是否被共享了?
|
||||
notebookId := noteService.GetNotebookId(noteId)
|
||||
if notebookId.Hex() == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// 判断notebook是否被共享
|
||||
if !db.Has(db.ShareNotebooks,
|
||||
bson.M{"UserId": bson.ObjectIdHex(userId), "ToUserId": bson.ObjectIdHex(updatedUserId), "NotebookId": notebookId}) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// updatedUserId是否有修改userId noteId的权限?
|
||||
func (this *ShareService) HasUpdatePerm(userId, updatedUserId, noteId string) bool {
|
||||
// 1. noteId是否被共享了?
|
||||
@ -340,8 +362,6 @@ func (this *ShareService) HasSharedNote(noteId, myUserId string) bool {
|
||||
// noteId的notebook是否共享了给我
|
||||
func (this *ShareService) HasSharedNotebook(noteId, myUserId, sharedUserId string) bool {
|
||||
notebookId := noteService.GetNotebookId(noteId)
|
||||
Log(noteId)
|
||||
Log(notebookId)
|
||||
if notebookId != "" {
|
||||
return db.Has(db.ShareNotebooks, bson.M{"NotebookId": notebookId,
|
||||
"UserId": bson.ObjectIdHex(sharedUserId),
|
||||
@ -509,4 +529,51 @@ func (this *ShareService) DeleteUserShareNoteAndNotebook(userId, toUserId string
|
||||
db.DeleteAll(db.HasShareNotes, query);
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 用户userId是否有修改noteId的权限
|
||||
func (this *ShareService) HasUpdateNotePerm(noteId, userId string) bool {
|
||||
if noteId == "" || userId == "" {
|
||||
return false;
|
||||
}
|
||||
note := noteService.GetNoteById(noteId)
|
||||
LogJ(note);
|
||||
if note.UserId != "" {
|
||||
noteUserId := note.UserId.Hex()
|
||||
if noteUserId != userId {
|
||||
// 是否是有权限协作的
|
||||
if this.HasUpdatePerm(noteUserId, userId, noteId) {
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 用户userId是否有修改noteId的权限
|
||||
func (this *ShareService) HasReadNotePerm(noteId, userId string) bool {
|
||||
if noteId == "" || userId == "" {
|
||||
return false;
|
||||
}
|
||||
note := noteService.GetNoteById(noteId)
|
||||
if note.UserId != "" {
|
||||
noteUserId := note.UserId.Hex()
|
||||
if noteUserId != userId {
|
||||
// 是否是有权限协作的
|
||||
if this.HasReadPerm(noteUserId, userId, noteId) {
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -53,7 +53,15 @@ func (this *TrashService) recoverNote(noteId, notebookId, userId string) bool {
|
||||
|
||||
// 删除trash
|
||||
func (this *TrashService) DeleteTrash(noteId, userId string) bool {
|
||||
return db.DeleteByIdAndUserId(db.Notes, noteId, userId)
|
||||
// delete note's attachs
|
||||
ok := attachService.DeleteAllAttachs(noteId, userId)
|
||||
|
||||
// delete note
|
||||
ok = db.DeleteByIdAndUserId(db.Notes, noteId, userId)
|
||||
// delete content
|
||||
ok = db.DeleteByIdAndUserId(db.NoteContents, noteId, userId)
|
||||
|
||||
return ok
|
||||
}
|
||||
|
||||
// 列出note, 排序规则, 还有分页
|
||||
|
@ -19,6 +19,7 @@ var blogService *BlogService
|
||||
var tokenService *TokenService
|
||||
var noteImageService *NoteImageService
|
||||
var fileService *FileService
|
||||
var attachService *AttachService
|
||||
|
||||
func init() {
|
||||
notebookService = &NotebookService{}
|
||||
@ -31,5 +32,6 @@ func init() {
|
||||
blogService = &BlogService{}
|
||||
tokenService = &TokenService{}
|
||||
fileService = &FileService{}
|
||||
attachService = &AttachService{}
|
||||
noteImageService = &NoteImageService{}
|
||||
}
|
@ -353,6 +353,7 @@ function log(o) {
|
||||
</i>Sort <i class="fa fa-angle-down"></i>
|
||||
-->
|
||||
</a>
|
||||
<!--
|
||||
<ul class="dropdown-menu" role="menu"
|
||||
aria-labelledby="dropdownMenu1"
|
||||
style="right: 3px; ! important; left: -100px; min-width: 100px;">
|
||||
@ -366,6 +367,7 @@ function log(o) {
|
||||
<li role="presentation"><a role="menuitem" tabindex="-1"
|
||||
href="#">Separated </a></li>
|
||||
</ul>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -466,6 +468,38 @@ function log(o) {
|
||||
<ul class="pull-right" id="editorTool">
|
||||
<li><a class="ios7-a " id="saveBtn" title="ctrl+s"
|
||||
data-toggle="dropdown">{{msg . "save"}}</a></li>
|
||||
|
||||
<li class="dropdown" id="attachDropdown">
|
||||
<a class="ios7-a dropdown-toggle" data-toggle="dropdown" id="showAttach">
|
||||
<!--
|
||||
<span class="fa fa-upload"></span>
|
||||
-->
|
||||
{{msg . "attachments"}}<span id="attachNum"></span>
|
||||
</a>
|
||||
<div class="dropdown-menu" id="attachMenu">
|
||||
<ul id="attachList">
|
||||
</ul>
|
||||
<form id="uploadAttach" method="post" action="/attach/UploadAttach" enctype="multipart/form-data">
|
||||
<div id="dropAttach">
|
||||
<a class="btn btn-success btn-choose-file">
|
||||
Choose File to Upload
|
||||
</a>
|
||||
<a class="btn btn-default" id="downloadAllBtn">
|
||||
<i class="fa fa-download"></i>
|
||||
Download All
|
||||
</a>
|
||||
<a class="btn btn-default" id="linkAllBtn">
|
||||
<i class="fa fa-link"></i>
|
||||
Link All
|
||||
</a>
|
||||
<input type="file" name="file" multiple/>
|
||||
</div>
|
||||
<div id="attachUploadMsg">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li><a class="ios7-a " id="tipsBtn"
|
||||
data-toggle="dropdown">{{msg . "editorTips"}}</a></li>
|
||||
<li><a class="ios7-a " id="contentHistory"
|
||||
@ -498,7 +532,7 @@ function log(o) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- leaui image -->
|
||||
<!-- leaui image drop image to editor-->
|
||||
<form id="upload" method="post" action="/file/uploadImageLeaui" enctype="multipart/form-data" style="margin-top: 5px;">
|
||||
<div id="drop">
|
||||
Drop images to here
|
||||
@ -982,19 +1016,17 @@ initSlimScroll();
|
||||
<link href="/public/mdeditor/editor/editor.css" rel="stylesheet">
|
||||
<script src="/public/mdeditor/editor/pagedown/Markdown.Converter-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/pagedown/Markdown.Sanitizer-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/pagedown/Markdown.Editor-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/pagedown/Markdown.Editor.js"></script>
|
||||
<script src="/public/mdeditor/editor/pagedown/local/Markdown.local.zh-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/Markdown.Extra-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/underscore-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/scrollLink.js"></script>
|
||||
<!--mathjax-->
|
||||
<!--
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({ tex2jax: { inlineMath: [['$','$'], ["\\(","\\)"]], processEscapes: true }, messageStyle: "none"});
|
||||
</script>
|
||||
<script src="/public/mdeditor/editor/mathJax-min.js"></script>
|
||||
<script src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
-->
|
||||
<script src="/public/mdeditor/editor/jquery.waitforimages-min.js"></script>
|
||||
<script src="/public/mdeditor/editor/google-code-prettify/prettify.js"></script>
|
||||
<script src="/public/mdeditor/editor/editor.js"></script>
|
||||
@ -1003,7 +1035,7 @@ initSlimScroll();
|
||||
<!-- context-menu -->
|
||||
<link rel="stylesheet" href="/js/contextmenu/css/contextmenu.css" type="text/css" />
|
||||
|
||||
<!-- version 2.0 -->
|
||||
<!-- js version 2.0 use require.js -->
|
||||
<script src="/js/require.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
@ -1011,14 +1043,18 @@ require.config({
|
||||
paths: {
|
||||
// 'jquery': 'js/jquery-1.9.0.min',
|
||||
'leaui_image': 'tinymce/plugins/leaui_image/public/js/for_editor',
|
||||
'attachment_upload': 'js/app/attachment_upload',
|
||||
'jquery.ui.widget': 'tinymce/plugins/leaui_image/public/js/jquery.ui.widget',
|
||||
'fileupload': '/tinymce/plugins/leaui_image/public/js/jquery.fileupload'
|
||||
},
|
||||
shim: {
|
||||
'fileupload': {deps: ['jquery.ui.widget']}
|
||||
}
|
||||
});
|
||||
require(['leaui_image'], function(leaui_image) {
|
||||
});
|
||||
require(['attachment_upload'], function(attachment_upload) {
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user