Skip to content

Commit ebb8a8a

Browse files
committed
附件上传管理优化
1 parent b4f9225 commit ebb8a8a

File tree

7 files changed

+63
-119
lines changed

7 files changed

+63
-119
lines changed

change.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@
3333

3434
## v2.10 升级日志
3535
- [x] 支持音频和视频上传
36+
- [ ] 如果开启了OSS云存储,则将音视频上传上去的同时将音视频设置为私有
3637
- [x] 支持音频和视频播放管理
3738
- [x] 管理后台,恢复和优化附件管理功能
3839
- [ ] 如果管理员或者用户是书籍项目所有人,则音视频链接支持直链播放,否则对音视频链接进行一定的防盗链处理
3940
- [ ] 内容阅读页面音频视频播放功能
40-
- [ ] ajax加载内容时,音视频不显示的问题
41+
- [ ] 音频和视频播放倍速控制
42+
- [ ] 音视频名称显示
43+
- [ ] 视频画中画播放
4144
- [x] 增加和升级API,使小程序和APP支持音频和视频播放,以及图片放大预览
4245
- [x] 优化`html2json`仓库,解析`HTML`内容,使小程序支持音频和视频播放功能,以及图片放大预览功能
4346
- [ ] 检测和隐藏相关功能

commands/command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ func ResolveCommand(args []string) {
250250
os.MkdirAll(uploads, 0666)
251251

252252
beego.BConfig.WebConfig.StaticDir["/static"] = filepath.Join("static")
253-
beego.BConfig.WebConfig.StaticDir["/uploads"] = uploads
253+
// beego.BConfig.WebConfig.StaticDir["/uploads"] = uploads
254254
beego.BConfig.WebConfig.ViewsPath = filepath.Join("views")
255255

256256
fonts := filepath.Join("static", "fonts")

controllers/BookController.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,9 +690,8 @@ func (this *BookController) Delete() {
690690
this.JsonResult(0, "ok")
691691
}
692692

693-
//发布书籍.
693+
// 发布书籍.
694694
func (this *BookController) Release() {
695-
696695
identify := this.GetString("identify")
697696
bookId := 0
698697
if this.Member.IsAdministrator() {

controllers/DocumentController.go

Lines changed: 28 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,15 @@ func (this *DocumentController) Read() {
291291
attach, err := models.NewAttachment().FindListByDocumentId(doc.DocumentId)
292292
if err == nil {
293293
doc.AttachList = attach
294+
if len(attach) > 0 {
295+
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>")
296+
for _, item := range attach {
297+
li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", item.HttpPath, item.FileName, item.FileName)
298+
content.WriteString(li)
299+
}
300+
content.WriteString("</ul></div>")
301+
doc.Release += content.String()
302+
}
294303
}
295304

296305
//文档阅读人次+1
@@ -632,7 +641,6 @@ func (this *DocumentController) Upload() {
632641
identify := this.GetString("identify")
633642
docId, _ := this.GetInt("doc_id")
634643
fileType := this.GetString("type")
635-
isAttach := true
636644

637645
if identify == "" {
638646
this.JsonResult(6001, "参数错误")
@@ -717,105 +725,58 @@ func (this *DocumentController) Upload() {
717725

718726
fileName := strconv.FormatInt(time.Now().UnixNano(), 16)
719727

720-
filePath := filepath.Join("uploads/projects", bookIdentify, time.Now().Format("200601"), fileName+ext)
721-
722-
path := filepath.Dir(filePath)
723-
724-
os.MkdirAll(path, os.ModePerm)
725-
726-
err = this.SaveToFile(name, filePath)
728+
prefix := "uploads"
729+
savePath := filepath.Join("projects", bookIdentify, time.Now().Format("200601"), fileName+ext)
730+
if utils.StoreType != utils.StoreOss {
731+
savePath = filepath.Join(prefix, savePath)
732+
}
733+
savePath = strings.ReplaceAll(savePath, "\\", "/")
734+
os.MkdirAll(filepath.Dir(savePath), os.ModePerm)
727735

736+
err = this.SaveToFile(name, savePath)
728737
if err != nil {
729738
beego.Error("SaveToFile => ", err)
730739
this.JsonResult(6005, "保存文件失败")
731740
}
741+
732742
attachment := models.NewAttachment()
733743
attachment.BookId = bookId
734744
attachment.FileName = moreFile.Filename
735745
attachment.CreateAt = this.Member.MemberId
736746
attachment.FileExt = ext
737-
attachment.FilePath = filePath
747+
attachment.FilePath = "/" + savePath
748+
attachment.HttpPath = attachment.FilePath
738749
attachment.DocumentId = docId
739750

740751
// 非附件
741752
if name != "editormd-file-file" {
742753
attachment.DocumentId = 0
743754
}
744755

745-
if fileInfo, err := os.Stat(filePath); err == nil {
756+
if fileInfo, err := os.Stat(savePath); err == nil {
746757
attachment.FileSize = float64(fileInfo.Size())
747758
}
748759

749-
if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") || strings.EqualFold(ext, ".png") || strings.EqualFold(ext, ".gif") {
750-
751-
attachment.HttpPath = "/" + strings.Replace(filePath, "\\", "/", -1)
752-
if strings.HasPrefix(attachment.HttpPath, "//") {
753-
attachment.HttpPath = string(attachment.HttpPath[1:])
754-
}
755-
isAttach = false
756-
}
757-
758-
err = attachment.Insert()
759-
760-
if err != nil {
761-
os.Remove(filePath)
760+
// 数据入库
761+
if err = attachment.Insert(); err != nil {
762+
os.Remove(savePath)
762763
beego.Error("Attachment Insert => ", err)
763764
this.JsonResult(6006, "文件保存失败")
764765
}
765-
if attachment.HttpPath == "" {
766-
attachment.HttpPath = beego.URLFor("DocumentController.DownloadAttachment", ":key", identify, ":attach_id", attachment.AttachmentId)
767-
768-
if err := attachment.Update(); err != nil {
769-
beego.Error("SaveToFile => ", err)
770-
this.JsonResult(6005, "保存文件失败")
771-
}
772-
}
773766

774-
//文件和图片分开放在书籍文件夹内
775-
var osspath = ""
776-
if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") || strings.EqualFold(ext, ".png") || strings.EqualFold(ext, ".gif") {
777-
osspath = fmt.Sprintf("projects/%v/%v", identify, fileName+filepath.Ext(attachment.HttpPath))
778-
} else {
779-
osspath = strings.Replace(filepath.Join("projects", identify, "files", fileName+ext), "\\", "/", -1)
780-
}
781-
782-
switch utils.StoreType {
783-
case utils.StoreOss:
784-
if err := store.ModelStoreOss.MoveToOss("."+attachment.HttpPath, osspath, true, false); err != nil {
767+
if utils.StoreType == utils.StoreOss {
768+
if err := store.ModelStoreOss.MoveToOss(savePath, savePath, true, false); err != nil {
785769
beego.Error(err.Error())
786770
}
787-
//attachment.HttpPath = this.OssDomain + "/" + osspath
788-
attachment.HttpPath = "/" + osspath
789-
case utils.StoreLocal:
790-
osspath = "uploads/" + osspath
791-
//图片是正确的,先不修改
792-
if strings.EqualFold(ext, ".jpg") || strings.EqualFold(ext, ".jpeg") || strings.EqualFold(ext, ".png") || strings.EqualFold(ext, ".gif") {
793-
if err := store.ModelStoreLocal.MoveToStore("."+attachment.HttpPath, osspath); err != nil {
794-
beego.Error(err.Error())
795-
}
796-
attachment.HttpPath = "/" + osspath
797-
attachment.FilePath = attachment.HttpPath
798-
} else {
799-
if err := store.ModelStoreLocal.MoveToStore(filePath, osspath); err != nil {
800-
beego.Error(err.Error())
801-
}
802-
attachment.FilePath = osspath
803-
}
804-
if err := attachment.Update(); err != nil {
805-
beego.Error("SaveToFile => ", err)
806-
this.JsonResult(6005, "保存文件失败")
807-
}
808771
}
809772

810-
attachment.HttpPath = "/" + strings.TrimLeft(attachment.FilePath, "./")
811-
812773
result := map[string]interface{}{
813774
"errcode": 0,
814775
"success": 1,
815776
"message": "ok",
816777
"url": attachment.HttpPath,
817778
"alt": attachment.FileName,
818-
"is_attach": isAttach,
779+
"is_attach": attachment.DocumentId > 0,
819780
"attach": attachment,
820781
}
821782
this.Ctx.Output.JSON(result, true, false)
@@ -973,7 +934,7 @@ func (this *DocumentController) Delete() {
973934
this.JsonResult(0, "ok")
974935
}
975936

976-
//获取或更新文档内容.
937+
// 获取或更新文档内容.
977938
func (this *DocumentController) Content() {
978939
identify := this.Ctx.Input.Param(":key")
979940
docId, err := this.GetInt("doc_id")

controllers/StaticController.go

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
package controllers
22

33
import (
4-
"io/ioutil"
4+
"fmt"
55
"net/http"
66
"path/filepath"
77
"strings"
8-
"time"
98

109
"github.com/TruthHun/BookStack/models"
1110

12-
"github.com/TruthHun/BookStack/models/store"
1311
"github.com/TruthHun/BookStack/utils"
1412
"github.com/astaxie/beego"
1513
)
1614

1715
type StaticController struct {
1816
beego.Controller
17+
OssDomain string
18+
}
19+
20+
func (this *StaticController) Prepare() {
21+
this.OssDomain = strings.TrimRight(beego.AppConfig.String("oss::Domain"), "/ ")
1922
}
2023

2124
func (this *StaticController) APP() {
@@ -26,6 +29,16 @@ func (this *StaticController) APP() {
2629
this.Abort("404")
2730
}
2831

32+
// Uploads 查询上传的静态资源。
33+
// 如果是音频和视频文件,需要根据后台设置而判断是否加密处理
34+
// 如果使用了OSS存储,则需要将文件处理好
35+
func (this *StaticController) Uploads() {
36+
file := strings.TrimLeft(this.GetString(":splat"), "./")
37+
path := strings.ReplaceAll(filepath.Join("uploads", file), "\\", "/")
38+
fmt.Println("===========", path)
39+
http.ServeFile(this.Ctx.ResponseWriter, this.Ctx.Request, path)
40+
}
41+
2942
//静态文件,这个加在路由的最后
3043
func (this *StaticController) StaticFile() {
3144
file := this.GetString(":splat")
@@ -40,41 +53,9 @@ func (this *StaticController) StaticFile() {
4053

4154
// 书籍静态文件
4255
func (this *StaticController) ProjectsFile() {
43-
prefix := "projects/"
44-
object := prefix + strings.TrimLeft(this.GetString(":splat"), "./")
45-
46-
//这里的时间只是起到缓存的作用
47-
t, _ := time.Parse("2006-01-02 15:04:05", "2006-01-02 15:04:05")
48-
date := t.Format(http.TimeFormat)
49-
since := this.Ctx.Request.Header.Get("If-Modified-Since")
50-
if since == date {
51-
this.Ctx.ResponseWriter.WriteHeader(http.StatusNotModified)
52-
return
53-
}
54-
56+
object := filepath.Join("projects/", strings.TrimLeft(this.GetString(":splat"), "./"))
5557
if utils.StoreType == utils.StoreOss { //oss
56-
staticDomain := strings.Trim(beego.AppConfig.DefaultString("static_domain", ""), "/")
57-
if staticDomain == "" {
58-
reader, err := store.NewOss().GetFileReader(object)
59-
if err != nil {
60-
beego.Error(err.Error())
61-
this.Abort("404")
62-
}
63-
defer reader.Close()
64-
65-
b, err := ioutil.ReadAll(reader)
66-
if err != nil {
67-
beego.Error(err.Error())
68-
this.Abort("404")
69-
}
70-
this.Ctx.ResponseWriter.Header().Set("Last-Modified", date)
71-
if strings.HasSuffix(object, ".svg") {
72-
this.Ctx.ResponseWriter.Header().Set("Content-Type", "image/svg+xml")
73-
}
74-
this.Ctx.ResponseWriter.Write(b)
75-
return
76-
}
77-
this.Redirect(staticDomain+"/"+object, 302)
58+
this.Redirect(this.OssDomain+"/"+object, 302)
7859
} else { //local
7960
this.Abort("404")
8061
}

models/document.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77

88
"github.com/TruthHun/gotil/mdtil"
99

10-
"bytes"
1110
"fmt"
1211

1312
"io/ioutil"
@@ -213,16 +212,16 @@ func (m *Document) ReleaseContent(bookId int, baseUrl string) {
213212
}
214213

215214
item.Release = ds.Content
216-
attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
217-
if err == nil && len(attachList) > 0 {
218-
content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>")
219-
for _, attach := range attachList {
220-
li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName)
221-
content.WriteString(li)
222-
}
223-
content.WriteString("</ul></div>")
224-
item.Release += content.String()
225-
}
215+
// attachList, err := NewAttachment().FindListByDocumentId(item.DocumentId)
216+
// if err == nil && len(attachList) > 0 {
217+
// content := bytes.NewBufferString("<div class=\"attach-list\"><strong>附件</strong><ul>")
218+
// for _, attach := range attachList {
219+
// li := fmt.Sprintf("<li><a href=\"%s\" target=\"_blank\" title=\"%s\">%s</a></li>", attach.HttpPath, attach.FileName, attach.FileName)
220+
// content.WriteString(li)
221+
// }
222+
// content.WriteString("</ul></div>")
223+
// item.Release += content.String()
224+
// }
226225

227226
// 采集图片与稳定内容连接替换
228227
if gq, err := goquery.NewDocumentFromReader(strings.NewReader(item.Release)); err == nil {

routers/web.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,5 +161,6 @@ func webRouter() {
161161
beego.Router("/local-render", &controllers.LocalhostController{}, "get,post:RenderMarkdown")
162162
beego.Router("/local-render-cover", &controllers.LocalhostController{}, "get:RenderCover")
163163
beego.Router("/projects/*", &controllers.StaticController{}, "get:ProjectsFile")
164+
beego.Router("/uploads/*", &controllers.StaticController{}, "get:Uploads")
164165
beego.Router("/*", &controllers.StaticController{}, "get:StaticFile")
165166
}

0 commit comments

Comments
 (0)