diff --git a/cmd/blog/main.go b/cmd/blog/main.go
index 99757d0..5975163 100644
--- a/cmd/blog/main.go
+++ b/cmd/blog/main.go
@@ -49,10 +49,10 @@ func runHTTPServer(endRun chan bool) {
root := filepath.Join(config.WorkDir, "assets")
e.Static("/static", root)
- // frontend pages
- page.RegisterRoutes(e)
// static files
file.RegisterRoutes(e)
+ // frontend pages
+ page.RegisterRoutes(e)
// unauthz api
admin.RegisterRoutes(e)
diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go
index f622c9c..6733059 100644
--- a/pkg/cache/cache.go
+++ b/pkg/cache/cache.go
@@ -71,8 +71,64 @@ type Cache struct {
ArticlesMap map[string]*model.Article // slug:article
}
-// PageArticles 文章翻页
-func (c *Cache) PageArticles(page int, pageSize int) (prev,
+// AddArticle 添加文章
+func (c *Cache) AddArticle(article *model.Article) error {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ // store
+ err := c.InsertArticle(context.Background(), article)
+ if err != nil {
+ return err
+ }
+ // 是否是草稿
+ if article.IsDraft {
+ return nil
+ }
+ // 正式发布文章
+ c.refreshCache(article, false)
+ return nil
+}
+
+// RepArticle 替换文章
+func (c *Cache) RepArticle(oldArticle, newArticle *model.Article) {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ c.ArticlesMap[newArticle.Slug] = newArticle
+ render.GenerateExcerptMarkdown(newArticle)
+ if newArticle.ID < config.Conf.BlogApp.General.StartID {
+ return
+ }
+ if oldArticle != nil { // 移除旧文章
+ c.refreshCache(oldArticle, true)
+ }
+ c.refreshCache(newArticle, false)
+}
+
+// DelArticles 删除文章
+func (c *Cache) DelArticles(ids []int) error {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ for _, id := range ids {
+ article, _ := c.FindArticleByID(id)
+
+ // set delete
+ err := c.UpdateArticle(context.Background(), id, map[string]interface{}{
+ "deleted_at": time.Now(),
+ })
+ if err != nil {
+ return err
+ }
+ // drop from tags,series,archives
+ c.refreshCache(article, true)
+ }
+ return nil
+}
+
+// PageArticleFE 文章翻页
+func (c *Cache) PageArticleFE(page int, pageSize int) (prev,
next int, articles []*model.Article) {
var l int
@@ -106,114 +162,37 @@ func (c *Cache) PageArticles(page int, pageSize int) (prev,
return
}
-// PageArticlesBE 后台文章分页
-// func (c *Cache) PageArticleBE(se int, kw string, draft, del bool, p, n int)(max int, artcs []*model.Article){
-//
-// }
+// PageArticleBE 后台文章分页
+func (c *Cache) PageArticleBE(se int, kw string, draft, del bool, p,
+ n int) ([]*model.Article, int) {
-// DeleteArticles 删除文章
-func (c *Cache) DeleteArticles(ids []int) error {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- for _, id := range ids {
- article, idx := c.FindArticleByID(id)
- // drop from linkedList
- if article.Prev == nil && article.Next != nil {
- article.Next.Prev = nil
- } else if article.Prev != nil && article.Next == nil {
- article.Prev.Next = nil
- } else if article.Prev != nil && article.Next != nil {
- article.Prev.Next = article.Next
- article.Next.Prev = article.Prev
- }
- // drop from articles
- c.Articles = append(c.Articles[:idx], c.Articles[idx+1:]...)
- delete(c.ArticlesMap, article.Slug)
- // set delete
- err := c.UpdateArticle(context.Background(), id, map[string]interface{}{
- "deletetime": time.Now(),
- })
- if err != nil {
- return err
- }
- // drop from tags,series,archives
- c.redelArticle(article)
+ search := store.SearchArticles{
+ Page: p,
+ Limit: n,
+ Fields: make(map[string]interface{}),
}
- return nil
-}
-
-// AddArticle 添加文章
-func (c *Cache) AddArticle(article *model.Article) error {
- err := c.InsertArticle(context.Background(), article)
+ if draft {
+ search.Fields[store.SearchArticleDraft] = true
+ } else if del {
+ search.Fields[store.SearchArticleTrash] = true
+ } else {
+ search.Fields[store.SearchArticleDraft] = false
+ if se > 0 {
+ search.Fields[store.SearchArticleSerieID] = se
+ }
+ if kw != "" {
+ search.Fields[store.SearchArticleTitle] = kw
+ }
+ }
+ articles, count, err := c.LoadArticleList(context.Background(), search)
if err != nil {
- return err
+ return nil, 0
}
- // 正式发布文章
- if !article.IsDraft {
- defer render.GenerateExcerptMarkdown(article)
-
- c.ArticlesMap[article.Slug] = article
- c.Articles = append([]*model.Article{article}, c.Articles...)
- sort.Sort(c.Articles)
-
- article, idx := c.FindArticleByID(article.ID)
- if idx == 0 && c.Articles[idx+1].ID >=
- config.Conf.BlogApp.General.StartID {
- article.Next = c.Articles[idx+1]
- c.Articles[idx+1].Prev = article
- } else if idx > 0 && c.Articles[idx-1].ID >=
- config.Conf.BlogApp.General.StartID {
- article.Prev = c.Articles[idx-1]
- if c.Articles[idx-1].Next != nil {
- article.Next = c.Articles[idx-1].Next
- c.Articles[idx-1].Next.Prev = article
- }
- c.Articles[idx-1].Next = article
- }
- c.readdArticle(article, true)
+ max := count / n
+ if max%n > 0 {
+ max++
}
- return nil
-}
-
-// ReplaceArticle 替换文章
-func (c *Cache) ReplaceArticle(oldArticle, newArticle *model.Article) {
- c.ArticlesMap[newArticle.Slug] = newArticle
- render.GenerateExcerptMarkdown(newArticle)
- if newArticle.ID < config.Conf.BlogApp.General.StartID {
- return
- }
- if oldArticle != nil {
- article, idx := c.FindArticleByID(oldArticle.ID)
- if article.Prev == nil && article.Next != nil {
- article.Next.Prev = nil
- } else if article.Prev != nil && article.Next == nil {
- article.Prev.Next = nil
- } else if article.Prev != nil && article.Next != nil {
- article.Prev.Next = article.Next
- article.Next.Prev = article.Prev
- }
- c.Articles = append(Ei.Articles[:idx], Ei.Articles[idx+1:]...)
-
- c.redelArticle(article)
- }
-
- c.Articles = append(c.Articles, newArticle)
- sort.Sort(c.Articles)
- _, idx := c.FindArticleByID(newArticle.ID)
- if idx == 0 && c.Articles[idx+1].ID >= config.Conf.BlogApp.General.StartID {
- newArticle.Next = c.Articles[idx+1]
- c.Articles[idx+1].Prev = newArticle
- } else if idx > 0 && c.Articles[idx-1].ID >=
- config.Conf.BlogApp.General.StartID {
- newArticle.Prev = Ei.Articles[idx-1]
- if c.Articles[idx-1].Next != nil {
- newArticle.Next = Ei.Articles[idx-1].Next
- c.Articles[idx-1].Next.Prev = newArticle
- }
- c.Articles[idx-1].Next = newArticle
- }
- c.readdArticle(newArticle, true)
+ return articles, max
}
// FindArticleByID 通过ID查找文章
@@ -226,86 +205,59 @@ func (c *Cache) FindArticleByID(id int) (*model.Article, int) {
return nil, -1
}
-// loadOrInit 读取数据或初始化
-func (c *Cache) loadOrInit() error {
- blogapp := config.Conf.BlogApp
- // blogger
- blogger := &model.Blogger{
- BlogName: strings.Title(blogapp.Account.Username),
- SubTitle: "Rome was not built in one day.",
- BeiAn: "蜀ICP备xxxxxxxx号-1",
- BTitle: fmt.Sprintf("%s's Blog", strings.Title(blogapp.Account.Username)),
- Copyright: `本站使用「署名 4.0 国际」创作共享协议,转载请注明作者及原网址。`,
- }
- created, err := c.LoadInsertBlogger(context.Background(), blogger)
- if err != nil {
- return err
- }
- c.Blogger = blogger
- if created { // init articles: about blogroll
- about := &model.Article{
- ID: 1, // 固定ID
- Author: blogapp.Account.Username,
- Title: "关于",
- Slug: "about",
- }
- err = c.InsertArticle(context.Background(), about)
- if err != nil {
- return err
- }
- // 推送到 disqus
- go internal.ThreadCreate(about, blogger.BTitle)
- blogroll := &model.Article{
- ID: 2, // 固定ID
- Author: blogapp.Account.Username,
- Title: "友情链接",
- Slug: "blogroll",
- }
- err = c.InsertArticle(context.Background(), blogroll)
- if err != nil {
- return err
- }
- }
- // account
- pwd := tools.EncryptPasswd(blogapp.Account.Password,
- blogapp.Account.Password)
+// refreshCache 刷新缓存
+func (c *Cache) refreshCache(article *model.Article, del bool) {
+ if del {
+ _, idx := c.FindArticleByID(article.ID)
- account := &model.Account{
- Username: blogapp.Account.Username,
- Password: pwd,
+ delete(c.ArticlesMap, article.Slug)
+ c.Articles = append(Ei.Articles[:idx], Ei.Articles[idx+1:]...)
+ // 从链表移除
+ c.recalcLinkedList(article, true)
+ // 从tag、serie、archive移除
+ c.redelArticle(article)
}
- _, err = c.LoadInsertAccount(context.Background(), account)
- if err != nil {
- return err
- }
- c.Account = account
- // all articles
- articles, err := c.LoadAllArticle(context.Background())
- if err != nil {
- return err
- }
- for i, v := range articles {
- // 渲染页面
- render.GenerateExcerptMarkdown(v)
+ // 添加文章
+ defer render.GenerateExcerptMarkdown(article)
- c.ArticlesMap[v.Slug] = v
- // 分析文章
- if v.ID < blogapp.General.StartID {
- continue
+ c.ArticlesMap[article.Slug] = article
+ c.Articles = append([]*model.Article{article}, c.Articles...)
+ sort.Sort(c.Articles)
+ // 从链表添加
+ c.recalcLinkedList(article, false)
+ // 从tag、serie、archive添加
+ c.readdArticle(article, true)
+}
+
+// recalcLinkedList 重算文章链表
+func (c *Cache) recalcLinkedList(article *model.Article, del bool) {
+ // 删除操作
+ if del {
+ if article.Prev == nil && article.Next != nil {
+ article.Next.Prev = nil
+ } else if article.Prev != nil && article.Next == nil {
+ article.Prev.Next = nil
+ } else if article.Prev != nil && article.Next != nil {
+ article.Prev.Next = article.Next
+ article.Next.Prev = article.Prev
}
- if i > 0 {
- v.Prev = Ei.Articles[i-1]
- }
- if Ei.Articles[i+1].ID >= blogapp.General.StartID {
- v.Next = Ei.Articles[i+1]
- }
- c.readdArticle(v, false)
+ return
+ }
+ // 添加操作
+ _, idx := c.FindArticleByID(article.ID)
+ if idx == 0 && c.Articles[idx+1].ID >=
+ config.Conf.BlogApp.General.StartID {
+ article.Next = c.Articles[idx+1]
+ c.Articles[idx+1].Prev = article
+ } else if idx > 0 && c.Articles[idx-1].ID >=
+ config.Conf.BlogApp.General.StartID {
+ article.Prev = c.Articles[idx-1]
+ if c.Articles[idx-1].Next != nil {
+ article.Next = c.Articles[idx-1].Next
+ c.Articles[idx-1].Next.Prev = article
+ }
+ c.Articles[idx-1].Next = article
}
- Ei.Articles = articles
- // 重建专题与归档
- PagesCh <- PageSeries
- PagesCh <- PageArchive
- return nil
}
// readdArticle 添加文章到tag、series、archive
@@ -396,6 +348,97 @@ func (c *Cache) redelArticle(article *model.Article) {
}
}
+// loadOrInit 读取数据或初始化
+func (c *Cache) loadOrInit() error {
+ blogapp := config.Conf.BlogApp
+ // blogger
+ blogger := &model.Blogger{
+ BlogName: strings.Title(blogapp.Account.Username),
+ SubTitle: "Rome was not built in one day.",
+ BeiAn: "蜀ICP备xxxxxxxx号-1",
+ BTitle: fmt.Sprintf("%s's Blog", strings.Title(blogapp.Account.Username)),
+ Copyright: `本站使用「署名 4.0 国际」创作共享协议,转载请注明作者及原网址。`,
+ }
+ created, err := c.LoadInsertBlogger(context.Background(), blogger)
+ if err != nil {
+ return err
+ }
+ c.Blogger = blogger
+ if created { // init articles: about blogroll
+ about := &model.Article{
+ ID: 1, // 固定ID
+ Author: blogapp.Account.Username,
+ Title: "关于",
+ Slug: "about",
+ UpdatedAt: time.Now(),
+ CreatedAt: time.Now(),
+ }
+ err = c.InsertArticle(context.Background(), about)
+ if err != nil {
+ return err
+ }
+ // 推送到 disqus
+ go internal.ThreadCreate(about, blogger.BTitle)
+ blogroll := &model.Article{
+ ID: 2, // 固定ID
+ Author: blogapp.Account.Username,
+ Title: "友情链接",
+ Slug: "blogroll",
+ UpdatedAt: time.Now(),
+ CreatedAt: time.Now(),
+ }
+ err = c.InsertArticle(context.Background(), blogroll)
+ if err != nil {
+ return err
+ }
+ }
+ // account
+ pwd := tools.EncryptPasswd(blogapp.Account.Password,
+ blogapp.Account.Password)
+
+ account := &model.Account{
+ Username: blogapp.Account.Username,
+ Password: pwd,
+ }
+ _, err = c.LoadInsertAccount(context.Background(), account)
+ if err != nil {
+ return err
+ }
+ c.Account = account
+ // all articles
+ search := store.SearchArticles{
+ Page: 1,
+ Limit: 9999,
+ Fields: map[string]interface{}{store.SearchArticleDraft: false},
+ }
+ articles, _, err := c.LoadArticleList(context.Background(), search)
+ if err != nil {
+ return err
+ }
+ for i, v := range articles {
+ // 渲染页面
+ render.GenerateExcerptMarkdown(v)
+
+ c.ArticlesMap[v.Slug] = v
+ // 分析文章
+ if v.ID < blogapp.General.StartID {
+ continue
+ }
+ if i > 0 {
+ v.Prev = Ei.Articles[i-1]
+ }
+ if Ei.Articles[i+1].ID >= blogapp.General.StartID {
+ v.Next = Ei.Articles[i+1]
+ }
+ c.readdArticle(v, false)
+ }
+ Ei.Articles = articles
+ // 重建专题与归档
+ PagesCh <- PageSeries
+ PagesCh <- PageArchive
+ return nil
+}
+
// regeneratePages 重新生成series,archive页面
func (c *Cache) regeneratePages() {
for {
diff --git a/pkg/cache/store/mongodb.go b/pkg/cache/store/mongodb.go
index 4c7a6e3..d5a9999 100644
--- a/pkg/cache/store/mongodb.go
+++ b/pkg/cache/store/mongodb.go
@@ -233,16 +233,6 @@ func (db *mongodb) RemoveArticle(ctx context.Context, id int) error {
return err
}
-// DeleteArticle 软删除文章,放入回收箱
-func (db *mongodb) DeleteArticle(ctx context.Context, id int) error {
- collection := db.Database(mongoDBName).Collection(collectionArticle)
-
- filter := bson.M{"id": id}
- update := bson.M{"$set": bson.M{"deletetime": time.Now()}}
- _, err := collection.UpdateOne(ctx, filter, update)
- return err
-}
-
// CleanArticles 清理回收站文章
func (db *mongodb) CleanArticles(ctx context.Context) error {
collection := db.Database(mongoDBName).Collection(collectionArticle)
@@ -270,16 +260,6 @@ func (db *mongodb) UpdateArticle(ctx context.Context, id int,
return err
}
-// RecoverArticle 恢复文章到草稿
-func (db *mongodb) RecoverArticle(ctx context.Context, id int) error {
- collection := db.Database(mongoDBName).Collection(collectionArticle)
-
- filter := bson.M{"id": id}
- update := bson.M{"$set": bson.M{"deletetime": time.Time{}, "isdraft": true}}
- _, err := collection.UpdateOne(ctx, filter, update)
- return err
-}
-
// LoadArticle 查找文章
func (db *mongodb) LoadArticle(ctx context.Context, id int) (*model.Article, error) {
collection := db.Database(mongoDBName).Collection(collectionArticle)
@@ -295,76 +275,55 @@ func (db *mongodb) LoadArticle(ctx context.Context, id int) (*model.Article, err
return article, err
}
-// LoadAllArticle 读取所有文章
-func (db *mongodb) LoadAllArticle(ctx context.Context) (model.SortedArticles, error) {
+// LoadArticleList 获取文章列表
+func (db *mongodb) LoadArticleList(ctx context.Context, search SearchArticles) (
+ model.SortedArticles, int, error) {
collection := db.Database(mongoDBName).Collection(collectionArticle)
- filter := bson.M{"isdraft": false, "deletetime": bson.M{"$eq": time.Time{}}}
- cur, err := collection.Find(ctx, filter)
- if err != nil {
- return nil, err
+ filter := bson.M{}
+ for k, v := range search.Fields {
+ switch k {
+ case SearchArticleDraft:
+ if ok := v.(bool); ok {
+ filter["is_draft"] = true
+ } else {
+ filter["is_draft"] = false
+ filter["deleted_at"] = bson.M{"$eq": time.Time{}}
+ }
+ case SearchArticleTitle:
+ filter["title"] = bson.M{
+ "$regex": v.(string),
+ "$options": "$i",
+ }
+ case SearchArticleSerieID:
+ filter["serie_id"] = v.(int)
+ case SearchArticleTrash:
+ filter["deleted_at"] = bson.M{"$nq": time.Time{}}
+ }
+ }
+ // search count
+ count, err := collection.CountDocuments(ctx, filter)
+ if err != nil {
+ return nil, 0, err
+ }
+ opts := options.Find().SetLimit(int64(search.Limit)).
+ SetSkip(int64((search.Page - 1) * search.Limit)).
+ SetSort(bson.M{"created_at": -1})
+ cur, err := collection.Find(ctx, filter, opts)
+ if err != nil {
+ return nil, 0, err
}
- defer cur.Close(ctx)
-
var articles model.SortedArticles
for cur.Next(ctx) {
obj := model.Article{}
err = cur.Decode(&obj)
if err != nil {
- return nil, err
+ return nil, 0, err
}
articles = append(articles, &obj)
}
sort.Sort(articles)
- return articles, nil
-}
-
-// LoadTrashArticles 读取回收箱
-func (db *mongodb) LoadTrashArticles(ctx context.Context) (model.SortedArticles, error) {
- collection := db.Database(mongoDBName).Collection(collectionArticle)
-
- filter := bson.M{"deletetime": bson.M{"$ne": time.Time{}}}
- cur, err := collection.Find(ctx, filter)
- if err != nil {
- return nil, err
- }
- defer cur.Close(ctx)
-
- var articles model.SortedArticles
- for cur.Next(ctx) {
- obj := model.Article{}
- err = cur.Decode(&obj)
- if err != nil {
- return nil, err
- }
- articles = append(articles, &obj)
- }
- sort.Sort(articles)
- return articles, nil
-}
-
-// LoadDraftArticles 读取草稿箱
-func (db *mongodb) LoadDraftArticles(ctx context.Context) (model.SortedArticles, error) {
- collection := db.Database(mongoDBName).Collection(collectionArticle)
-
- filter := bson.M{"isdraft": true}
- cur, err := collection.Find(ctx, filter)
- if err != nil {
- return nil, err
- }
- defer cur.Close(ctx)
-
- var articles model.SortedArticles
- for cur.Next(ctx) {
- obj := model.Article{}
- err = cur.Decode(&obj)
- if err != nil {
- return nil, err
- }
- articles = append(articles, &obj)
- }
- sort.Sort(articles)
- return articles, nil
+ return articles, int(count), nil
}
// counter counter
diff --git a/pkg/cache/store/store.go b/pkg/cache/store/store.go
index c5f0b1e..2cf5746 100644
--- a/pkg/cache/store/store.go
+++ b/pkg/cache/store/store.go
@@ -15,6 +15,21 @@ var (
stores = make(map[string]Driver)
)
+// search field
+const (
+ SearchArticleDraft = "draft"
+ SearchArticleTrash = "trash"
+ SearchArticleTitle = "title"
+ SearchArticleSerieID = "serieid"
+)
+
+// SearchArticles 搜索字段
+type SearchArticles struct {
+ Page int // 第几页/1
+ Limit int // 每页大小
+ Fields map[string]interface{} // 字段:值
+}
+
// Store 存储后端
type Store interface {
// LoadInsertBlogger 读取或创建博客
@@ -40,22 +55,14 @@ type Store interface {
InsertArticle(ctx context.Context, article *model.Article) error
// RemoveArticle 硬删除文章
RemoveArticle(ctx context.Context, id int) error
- // DeleteArticle 软删除文章,放入回收箱
- DeleteArticle(ctx context.Context, id int) error
// CleanArticles 清理回收站文章
CleanArticles(ctx context.Context) error
// UpdateArticle 更新文章
UpdateArticle(ctx context.Context, id int, fields map[string]interface{}) error
- // RecoverArticle 恢复文章到草稿
- RecoverArticle(ctx context.Context, id int) error
// LoadArticle 查找文章
LoadArticle(ctx context.Context, id int) (*model.Article, error)
- // LoadAllArticle 读取所有文章
- LoadAllArticle(ctx context.Context) (model.SortedArticles, error)
- // LoadTrashArticles 读取回收箱
- LoadTrashArticles(ctx context.Context) (model.SortedArticles, error)
- // LoadDraftArticles 读取草稿箱
- LoadDraftArticles(ctx context.Context) (model.SortedArticles, error)
+ // LoadArticleList 查找文章列表
+ LoadArticleList(ctx context.Context, search SearchArticles) (model.SortedArticles, int, error)
}
// Driver 存储驱动
diff --git a/pkg/core/blog/admin/admin.go b/pkg/core/blog/admin/admin.go
index d0588c8..c9586a8 100644
--- a/pkg/core/blog/admin/admin.go
+++ b/pkg/core/blog/admin/admin.go
@@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"strconv"
+ "strings"
"time"
"github.com/eiblog/eiblog/pkg/cache"
@@ -37,6 +38,18 @@ func RegisterRoutesAuthz(group gin.IRoutes) {
group.GET("/draft-delete", handleDraftDelete)
group.POST("/api/account", handleAPIAccount)
+ group.POST("/api/blog", handleAPIBlogger)
+ group.POST("/api/password", handleAPIPassword)
+ group.POST("/api/post-delete", handleAPIPostDelete)
+ group.POST("/api/post-add", handleAPIPostCreate)
+ group.POST("/api/serie-delete", handleAPISerieDelete)
+ group.POST("/api/serie-add", handleAPISerieCreate)
+ group.POST("/api/serie-sort", handleAPISerieSort)
+ group.POST("/api/draft-delete", handleDraftDelete)
+ group.POST("/api/trash-delete", handleAPITrashDelete)
+ group.POST("/api/trash-recover", handleAPITrashRecover)
+ group.POST("/api/file-upload", handleAPIQiniuUpload)
+ group.POST("/api/file-delete", handleAPIQiniuDelete)
}
// handleAcctLogin 登录接口
@@ -67,7 +80,7 @@ func handleAcctLogin(c *gin.Context) {
c.Redirect(http.StatusFound, "/admin/profile")
}
-// handleDraftDelete 删除草稿
+// handleDraftDelete 删除草稿, 物理删除
func handleDraftDelete(c *gin.Context) {
id, err := strconv.Atoi(c.Query("cid"))
if err != nil || id < 1 {
@@ -189,7 +202,7 @@ func handleAPIPostDelete(c *gin.Context) {
}
ids = append(ids, id)
}
- err := cache.Ei.DeleteArticles(ids)
+ err := cache.Ei.DelArticles(ids)
if err != nil {
logrus.Error("handleAPIPostDelete.DeleteArticles: ", err)
@@ -261,7 +274,7 @@ func handleAPIPostCreate(c *gin.Context) {
if err != nil || cid < 1 {
err = cache.Ei.AddArticle(article)
if err != nil {
- logrus.Error("handleAPIPostCreate.InsertArticle: ", err)
+ logrus.Error("handleAPIPostCreate.AddArticle: ", err)
return
}
if !article.IsDraft {
@@ -289,12 +302,12 @@ func handleAPIPostCreate(c *gin.Context) {
artc.UpdatedAt = time.Now()
}
// 数据库更新
- err = cache.Ei.UpdateArticle(context.Background(), artc.ID, map[string]interface{}{
+ err = cache.Ei.UpdateArticle(context.Background(), article.ID, map[string]interface{}{
"title": article.Title,
"content": article.Content,
"serie_id": article.SerieID,
- "tags": article.Tags,
"is_draft": article.IsDraft,
+ "tags": article.Tags,
"updated_at": article.UpdatedAt,
"created_at": article.CreatedAt,
})
@@ -303,7 +316,7 @@ func handleAPIPostCreate(c *gin.Context) {
return
}
if !artc.IsDraft {
- cache.Ei.ReplaceArticle(artc, article)
+ cache.Ei.RepArticle(artc, article)
// 异步执行,快
go func() {
// elastic
@@ -349,6 +362,12 @@ func handleAPISerieDelete(c *gin.Context) {
responseNotice(c, NoticeSuccess, "删除成功", "")
}
+// handleAPISerieSort 专题排序
+func handleAPISerieSort(c *gin.Context) {
+ v := c.PostFormArray("mid[]")
+ logrus.Debug(v)
+}
+
// handleAPISerieCreate 添加专题,如果专题有提交 mid 即更新专题
func handleAPISerieCreate(c *gin.Context) {
name := c.PostForm("name")
@@ -396,6 +415,92 @@ func handleAPISerieCreate(c *gin.Context) {
responseNotice(c, NoticeSuccess, "操作成功", "")
}
+// handleAPITrashDelete 删除回收箱, 物理删除
+func handleAPITrashDelete(c *gin.Context) {
+ for _, v := range c.PostFormArray("mid[]") {
+ id, err := strconv.Atoi(v)
+ if err != nil || id < 1 {
+ responseNotice(c, NoticeNotice, "参数错误", "")
+ return
+ }
+ err = cache.Ei.RemoveArticle(context.Background(), id)
+ if err != nil {
+ responseNotice(c, NoticeNotice, err.Error(), "")
+ return
+ }
+ }
+ responseNotice(c, NoticeSuccess, "删除成功", "")
+}
+
+// handleAPITrashRecover 恢复到草稿
+func handleAPITrashRecover(c *gin.Context) {
+ for _, v := range c.PostFormArray("mid[]") {
+ id, err := strconv.Atoi(v)
+ if err != nil || id < 1 {
+ responseNotice(c, NoticeNotice, "参数错误", "")
+ return
+
+ }
+ err = cache.Ei.UpdateArticle(context.Background(), id, map[string]interface{}{
+ "deleted_at": time.Time{},
+ "is_draft": true,
+ })
+ if err != nil {
+ responseNotice(c, NoticeNotice, err.Error(), "")
+ return
+ }
+ }
+ responseNotice(c, NoticeSuccess, "恢复成功", "")
+}
+
+// handleAPIQiniuUpload 上传文件
+func handleAPIQiniuUpload(c *gin.Context) {
+ type Size interface {
+ Size() int64
+ }
+ file, header, err := c.Request.FormFile("file")
+ if err != nil {
+ logrus.Error("handleAPIQiniuUpload.FormFile: ", err)
+ c.String(http.StatusBadRequest, err.Error())
+ return
+ }
+ s, ok := file.(Size)
+ if !ok {
+ logrus.Error("assert failed")
+ c.String(http.StatusBadRequest, "false")
+ return
+ }
+ filename := strings.ToLower(header.Filename)
+ url, err := internal.QiniuUpload(filename, s.Size(), file)
+ if err != nil {
+ logrus.Error("handleAPIQiniuUpload.QiniuUpload: ", err)
+ c.String(http.StatusBadRequest, err.Error())
+ return
+ }
+ typ := header.Header.Get("Content-Type")
+ c.JSON(http.StatusOK, gin.H{
+ "title": filename,
+ "isImage": typ[:5] == "image",
+ "url": url,
+ "bytes": fmt.Sprintf("%dkb", s.Size()/1000),
+ })
+}
+
+// handleAPIQiniuDelete 删除文件
+func handleAPIQiniuDelete(c *gin.Context) {
+ defer c.String(http.StatusOK, "删掉了吗?鬼知道。。。")
+
+ name := c.PostForm("title")
+ if name == "" {
+ logrus.Error("handleAPIQiniuDelete.PostForm: 参数错误")
+ return
+ }
+ err := internal.QiniuDelete(name)
+ if err != nil {
+ logrus.Error("handleAPIQiniuDelete.QiniuDelete: ", err)
+ }
+}
+
// parseLocationDate 解析日期
func parseLocationDate(date string) time.Time {
t, err := time.ParseInLocation("2006-01-02 15:04", date, time.Local)
diff --git a/pkg/core/blog/file/timer.go b/pkg/core/blog/file/timer.go
index 0dc0721..295ed6e 100644
--- a/pkg/core/blog/file/timer.go
+++ b/pkg/core/blog/file/timer.go
@@ -42,7 +42,7 @@ func timerFeed() {
}
now := time.Now()
- _, _, articles := cache.Ei.PageArticles(1, 20)
+ _, _, articles := cache.Ei.PageArticleFE(1, 20)
params := map[string]interface{}{
"Titile": cache.Ei.Blogger.BTitle,
"SubTitle": cache.Ei.Blogger.SubTitle,
diff --git a/pkg/core/blog/page/be.go b/pkg/core/blog/page/be.go
index d627c5b..5d5f1fa 100644
--- a/pkg/core/blog/page/be.go
+++ b/pkg/core/blog/page/be.go
@@ -11,6 +11,7 @@ import (
"strconv"
"github.com/eiblog/eiblog/pkg/cache"
+ "github.com/eiblog/eiblog/pkg/cache/store"
"github.com/eiblog/eiblog/pkg/config"
"github.com/eiblog/eiblog/pkg/core/blog"
"github.com/eiblog/eiblog/pkg/model"
@@ -23,7 +24,7 @@ import (
func baseBEParams(c *gin.Context) gin.H {
return gin.H{
"Author": cache.Ei.Account.Username,
- "Qiniu": config.Conf.BlogApp.Qiniu.Domain,
+ "Qiniu": config.Conf.BlogApp.Qiniu,
}
}
@@ -103,8 +104,8 @@ func handleAdminPosts(c *gin.Context) {
params["Serie"] = se
params["KW"] = kw
var max int
- // TODO
- // max, params["List"] = cache.Ei.PageListBack(se, kw, false, false, pg, setting.Conf.General.PageSize)
+ params["List"], max = cache.Ei.PageArticleBE(se, kw, false, false,
+ pg, config.Conf.BlogApp.General.PageSize)
if pg < max {
vals.Set("page", fmt.Sprint(pg+1))
params["Next"] = vals.Encode()
@@ -171,7 +172,12 @@ func handleAdminDraft(c *gin.Context) {
params["Manage"] = true
params["Path"] = c.Request.URL.Path
var err error
- params["List"], err = cache.Ei.LoadDraftArticles(context.Background())
+ search := store.SearchArticles{
+ Page: 1,
+ Limit: 9999,
+ Fields: map[string]interface{}{store.SearchArticleDraft: true},
+ }
+ params["List"], _, err = cache.Ei.LoadArticleList(context.Background(), search)
if err != nil {
logrus.Error("handleDraft.LoadDraftArticles: ", err)
c.Status(http.StatusBadRequest)
@@ -188,9 +194,14 @@ func handleAdminTrash(c *gin.Context) {
params["Manage"] = true
params["Path"] = c.Request.URL.Path
var err error
- params["List"], err = cache.Ei.LoadTrashArticles(context.Background())
+ search := store.SearchArticles{
+ Page: 1,
+ Limit: 9999,
+ Fields: map[string]interface{}{store.SearchArticleTrash: true},
+ }
+ params["List"], _, err = cache.Ei.LoadArticleList(context.Background(), search)
if err != nil {
- logrus.Error("handleTrash.LoadTrashArticles: ", err)
+ logrus.Error("handleTrash.LoadArticleList: ", err)
c.HTML(http.StatusBadRequest, "backLayout.html", params)
return
}
diff --git a/pkg/core/blog/page/fe.go b/pkg/core/blog/page/fe.go
index 7ef478a..3f0e27b 100644
--- a/pkg/core/blog/page/fe.go
+++ b/pkg/core/blog/page/fe.go
@@ -64,7 +64,7 @@ func handleHomePage(c *gin.Context) {
if err != nil || pn < 1 {
pn = 1
}
- params["Prev"], params["Next"], params["List"] = cache.Ei.PageArticles(pn,
+ params["Prev"], params["Next"], params["List"] = cache.Ei.PageArticleFE(pn,
config.Conf.BlogApp.General.PageNum)
renderHTMLHomeLayout(c, "home", params)