diff --git a/internal/async/PublishArticle.go b/internal/async/PublishArticle.go index a38de93..0f6f6cd 100644 --- a/internal/async/PublishArticle.go +++ b/internal/async/PublishArticle.go @@ -1,6 +1,7 @@ package async import ( + "blog/internal/consts" "blog/internal/model/blog" "blog/third_party/database" "context" @@ -27,7 +28,7 @@ func init() { database.GormTemplate.Table("blog_articles").Where("id = ?", id).UpdateColumn("publish_time", time) database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(article) - database.RedisTemplate.ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(article.PublishTime), Member: article}) + database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: article}) } }() } diff --git a/internal/async/PublishDiary.go b/internal/async/PublishDiary.go index 955d8c1..7a3e31e 100644 --- a/internal/async/PublishDiary.go +++ b/internal/async/PublishDiary.go @@ -1,6 +1,7 @@ package async import ( + "blog/internal/consts" "blog/internal/model/blog" "blog/third_party/database" "context" @@ -22,7 +23,7 @@ func init() { var diary blog.BlogDiary database.GormTemplate.Table("blog_diaries").Where("id = ?", id).First(&diary) - database.RedisTemplate.ZAdd(ctx, "blog:diary:latest", redis.Z{Score: float64(diary.PublishTime), Member: diary}) + database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(diary.PublishTime), Member: diary}) } }() } diff --git a/internal/async/ViewRecord.go b/internal/async/ViewRecord.go index 5aa8e94..0dabfeb 100644 --- a/internal/async/ViewRecord.go +++ b/internal/async/ViewRecord.go @@ -1,6 +1,7 @@ package async import ( + "blog/internal/consts" "blog/third_party/database" "context" "log" @@ -30,7 +31,7 @@ func init() { record.Id = uuid.NewString() database.GormTemplate.Table("blog_view_record").Create(&record) ctx := context.Background() - database.RedisTemplate.HIncrBy(ctx, "blog:view:record", relId, 1) + database.RedisTemplate.HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, relId, 1) } diff --git a/internal/consts/ArticleState.go b/internal/consts/ArticleState.go new file mode 100644 index 0000000..d001f19 --- /dev/null +++ b/internal/consts/ArticleState.go @@ -0,0 +1,8 @@ +package consts + +//文章状态常量 +const ARTICLE_STATE_PUBLISH string = "publish" +const ARTICLE_STATE_DRAFT string = "draft" + +const ARTICLE_CONTENT_TYPE_MARKDOWN string = "markdown" +const ARTICLE_CONTENT_TYPE_TINYMCE string = "tinymce" diff --git a/internal/consts/ContentState.go b/internal/consts/ContentState.go new file mode 100644 index 0000000..5ec912b --- /dev/null +++ b/internal/consts/ContentState.go @@ -0,0 +1,6 @@ +package consts + +//文本状态常量 + +const CONTENT_STATE_PUBLISH string = "publish" +const CONTENT_STATE_DOWN string = "down" diff --git a/internal/consts/RedisConst.go b/internal/consts/RedisConst.go new file mode 100644 index 0000000..d7e9db6 --- /dev/null +++ b/internal/consts/RedisConst.go @@ -0,0 +1,21 @@ +package consts + +//Redis + +//文章相关Key常量 +const REDIS_BLOG_ARTICLE string = "blog:article:" +const REDIS_BLOG_ARTICLE_LATEST string = "blog:article:latest" + +//日记相关Key常量 +const REDIS_BLOG_DIARY string = "blog:diary:" +const REDIS_BLOG_DIARY_LATEST string = "blog:diary:latest" + +//文件相关Key常量 +const REDIS_FILE string = "blog:file:" +const REDIS_FILE_BYTES string = "blog:file:bytes" + +//文本相关Key常量 +const REDIS_BLOG_CONTENT string = "blog:content:" + +//点击量相关Key常量 +const REDIS_BLOG_VIEW_RECORD string = "blog:view:record" diff --git a/internal/controller/ArticleController.go b/internal/controller/ArticleController.go index abedbb7..0bb3d6d 100644 --- a/internal/controller/ArticleController.go +++ b/internal/controller/ArticleController.go @@ -2,6 +2,7 @@ package controller import ( "blog/internal/async" + "blog/internal/consts" "blog/internal/model/AjaxResult" "blog/internal/model/blog" "blog/internal/service" @@ -28,7 +29,7 @@ func (ctrl *ArticleController) Get() { func (ctrl *ArticleController) GetLatest() { ctx := context.Background() var slices []blog.BlogArticle - err := database.RedisTemplate.ZRevRange(ctx, "blog:article:latest", 0, 10).ScanSlice(&slices) + err := database.RedisTemplate.ZRevRange(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, 0, 10).ScanSlice(&slices) if err != nil { log.Println(err) ctrl.Ctx.JSON(AjaxResult.Error("加载错误")) @@ -38,7 +39,7 @@ func (ctrl *ArticleController) GetLatest() { for i := range slices { article := &slices[i] id := article.Id - viewRecord, _ := database.RedisTemplate.HGet(ctx, "blog:view:record", id).Int() + viewRecord, _ := database.RedisTemplate.HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int() article.ViewRecord = viewRecord } @@ -58,7 +59,7 @@ func (ctrl *ArticleController) ViewArticle() { content := service.ContentService.GetContentByCache(articleId) ctrl.Ctx.ViewData("article", article) ctrl.Ctx.ViewData("content", content) - if article.ContentType == "markdown" { + if article.ContentType == consts.ARTICLE_CONTENT_TYPE_MARKDOWN { ctrl.Ctx.View("blog/article/article_md.html") return } diff --git a/internal/controller/DiaryController.go b/internal/controller/DiaryController.go index b07002b..63a70d3 100644 --- a/internal/controller/DiaryController.go +++ b/internal/controller/DiaryController.go @@ -1,6 +1,7 @@ package controller import ( + "blog/internal/consts" "blog/internal/model/AjaxResult" "blog/internal/model/blog" "blog/internal/service" @@ -24,7 +25,7 @@ func (ctrl *DiaryController) Get() { func (ctrl *DiaryController) GetLatest() { ctx := context.Background() var slices []blog.BlogDiary - err := database.RedisTemplate.ZRevRange(ctx, "blog:diary:latest", 0, 5).ScanSlice(&slices) + err := database.RedisTemplate.ZRevRange(ctx, consts.REDIS_BLOG_DIARY_LATEST, 0, 5).ScanSlice(&slices) if err != nil { log.Println(err) ctrl.Ctx.JSON(AjaxResult.Error("加载错误")) diff --git a/internal/controller/FileController.go b/internal/controller/FileController.go index 37b8824..74d609c 100644 --- a/internal/controller/FileController.go +++ b/internal/controller/FileController.go @@ -2,6 +2,7 @@ package controller import ( "blog/internal/service" + "net/url" "github.com/kataras/iris/v12" "github.com/kataras/iris/v12/mvc" @@ -14,10 +15,13 @@ type FileController struct { } func (ctrl *FileController) ViewFile() { - relId := ctrl.Ctx.Params().Get("id") - bytes := service.FileService.GetFile(relId) - ctrl.Ctx.Write(bytes) - + id := ctrl.Ctx.Params().Get("id") + file, err := service.FileService.GetFile(id) + if err != nil { + return + } + ctrl.Ctx.Header("Content-Disposition", "attachment;filename="+url.QueryEscape(file.FileName)) + ctrl.Ctx.Write(file.Data) } func (ctrl *FileController) BeforeActivation(activation mvc.BeforeActivation) { diff --git a/internal/controller/admin/FileController.go b/internal/controller/admin/FileController.go index e6e7542..6e6d22f 100644 --- a/internal/controller/admin/FileController.go +++ b/internal/controller/admin/FileController.go @@ -2,6 +2,8 @@ package admin import ( "blog/internal/model/admin" + "blog/internal/service" + "blog/third_party/SessionUtil" "blog/third_party/database" "time" @@ -23,6 +25,18 @@ type uploadResponse struct { Location string `json:"location"` } +func (ctrl *FileController) Get() { + ctrl.Ctx.View("/admin/file/index.html") +} + +func (ctrl *FileController) GetList() { + page := ctrl.Ctx.URLParamIntDefault("page", 0) + itemsPerPage := ctrl.Ctx.URLParamIntDefault("itemsPerPage", 10) + pages := service.FileService.PageSysFiles(page, itemsPerPage) + + ctrl.Ctx.JSON(pages) +} + func (ctrl *FileController) PostUpload() { file, fileHeader, err := ctrl.Ctx.FormFile("editormd-image-file") if err != nil { @@ -31,13 +45,22 @@ func (ctrl *FileController) PostUpload() { return } } + user := SessionUtil.GetUser(ctrl.Session) fileId := uuid.NewString() fileName := fileHeader.Filename fileSize := fileHeader.Size var bytes []byte = make([]byte, fileSize) file.Read(bytes) - sysFile := admin.SysFile{Id: fileId, FileName: fileName, FileSize: fileSize, CreateTime: time.Now().UnixMilli(), Data: bytes, State: "1", Del: 0} + sysFile := admin.SysFile{ + Id: fileId, + FileName: fileName, + FileSize: fileSize, + CreateBy: user.Username, + CreateTime: time.Now().UnixMilli(), + Data: bytes, State: "1", + Del: 0, + } err = database.GormTemplate.Transaction(func(tx *gorm.DB) error { err2 := tx.Table("common_files").Create(sysFile).Error return err2 diff --git a/internal/model/vo/CommonFiles.go b/internal/model/vo/CommonFiles.go index 8e73558..56890fc 100644 --- a/internal/model/vo/CommonFiles.go +++ b/internal/model/vo/CommonFiles.go @@ -5,7 +5,7 @@ import "encoding/json" type CommonFiles struct { Id string `json:"id" gorm:"primary_key"` FileName string `json:"fileName"` - Data []byte + Data []byte `json:"-"` Sort int32 `json:"sort"` CreateBy string `json:"-"` CreateTime int64 `json:"-"` @@ -15,11 +15,11 @@ type CommonFiles struct { Del int `json:"-"` } -func (article *CommonFiles) MarshalBinary() (data []byte, err error) { +func (file *CommonFiles) MarshalBinary() (data []byte, err error) { // encoding.BinaryMarshaler - return json.Marshal(article) + return json.Marshal(file) } -func (article *CommonFiles) UnmarshalBinary(data []byte) (err error) { - return json.Unmarshal(data, article) +func (file *CommonFiles) UnmarshalBinary(data []byte) (err error) { + return json.Unmarshal(data, file) } diff --git a/internal/service/ArticleService.go b/internal/service/ArticleService.go index 56b2030..e3cc86b 100644 --- a/internal/service/ArticleService.go +++ b/internal/service/ArticleService.go @@ -1,6 +1,7 @@ package service import ( + "blog/internal/consts" "blog/internal/model/admin" "blog/internal/model/blog" "blog/internal/model/vo" @@ -23,13 +24,13 @@ var ArticleService articleService func (*articleService) InitArticleData() { var articleSlice []blog.BlogArticle - result := database.GormTemplate.Where("state = ?", "publish").Find(&articleSlice) + result := database.GormTemplate.Where("state = ?", consts.ARTICLE_STATE_PUBLISH).Find(&articleSlice) log.Println("文章初始化数据加载量:", result.RowsAffected) ctx := context.Background() for _, article := range articleSlice { // log.Println(article) publishTime := article.PublishTime - err := database.RedisTemplate.ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(publishTime), Member: &article}).Err() + err := database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err() if err != nil { log.Println(err) } @@ -43,14 +44,14 @@ func (*articleService) InitArticleData() { database.GormTemplate.Table("blog_view_record").Select("rel_id ,count(1) counts").Group("rel_id").Find(&records) for _, val := range records { - database.RedisTemplate.HSet(ctx, "blog:view:record", map[string]any{val.RelId: val.Counts}) + database.RedisTemplate.HSet(ctx, consts.REDIS_BLOG_VIEW_RECORD, map[string]any{val.RelId: val.Counts}) } } func (*articleService) GetBlogArticle(id string) blog.BlogArticle { ctx := context.Background() var article blog.BlogArticle - key := "blog:article:" + id + key := consts.REDIS_BLOG_ARTICLE + id err := database.RedisTemplate.HGetAll(ctx, key).Scan(&article) if err != nil || article.Id == "" { database.GormTemplate.Table("blog_articles").Where("id = ?", id).First(&article) @@ -93,7 +94,7 @@ func (*articleService) CreateArticle(articel *admin.AdminArticle) (string, error articel.CreateTime = time articel.UpdateTime = time articel.Del = 0 - articel.State = "draft" + articel.State = consts.ARTICLE_STATE_DRAFT err := database.GormTemplate.Transaction(func(tx *gorm.DB) error { contentId := uuid.NewString() @@ -134,19 +135,19 @@ func (*articleService) PublishArticle(id string) error { return err } - if article.State != "draft" { + if article.State != consts.ARTICLE_STATE_DRAFT { return errors.New("发布失败,文章状态不是起草状态,无法发布") } article.PublishTime = now - article.State = "publish" + article.State = consts.ARTICLE_STATE_PUBLISH err = database.GormTemplate.Transaction(func(tx *gorm.DB) error { var txErr error = tx.Table("blog_articles").Updates(&article).Error if txErr != nil { return errors.New("文章更新错误") } - txErr = ContentService.UpdataState(id, "publish") + txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_PUBLISH) if txErr != nil { return errors.New("文本状态更新错误") } @@ -156,11 +157,11 @@ func (*articleService) PublishArticle(id string) error { } ctx := context.Background() - txErr = database.RedisTemplate.ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(article.PublishTime), Member: &article}).Err() + txErr = database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: &article}).Err() if txErr != nil { return errors.New("缓存错误") } - txErr = database.RedisTemplate.Set(ctx, "blog:content:"+id, content.Content, time.Duration(0)).Err() + txErr = database.RedisTemplate.Set(ctx, consts.REDIS_BLOG_CONTENT+id, content.Content, time.Duration(0)).Err() return txErr }) @@ -175,14 +176,14 @@ func (*articleService) UnPublishArticle(id string) error { return err } - if article.State != "publish" { + if article.State != consts.CONTENT_STATE_PUBLISH { return errors.New("撤下失败,文章状态不是已发布状态,无法撤下") } err = database.GormTemplate.Transaction(func(tx *gorm.DB) error { var txErr error ctx := context.Background() - txErr = database.RedisTemplate.ZRemRangeByScore(ctx, "blog:article:latest", + txErr = database.RedisTemplate.ZRemRangeByScore(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, strconv.FormatFloat(float64(article.PublishTime), 'E', -1, 64), strconv.FormatFloat(float64(article.PublishTime), 'E', -1, 64), ).Err() @@ -191,18 +192,18 @@ func (*articleService) UnPublishArticle(id string) error { return errors.New("缓存错误") } - txErr = database.RedisTemplate.Del(ctx, "blog:content:"+id).Err() + txErr = database.RedisTemplate.Del(ctx, consts.REDIS_BLOG_CONTENT+id).Err() if txErr != nil { return errors.New("缓存错误") } - article.State = "draft" + article.State = consts.ARTICLE_STATE_DRAFT article.PublishTime = -1 txErr = tx.Table("blog_articles").Updates(&article).Error if txErr != nil { return errors.New("文章状态更新错误") } - txErr = ContentService.UpdataState(id, "down") + txErr = ContentService.UpdataState(id, consts.CONTENT_STATE_DOWN) return txErr }) diff --git a/internal/service/ContentService.go b/internal/service/ContentService.go index c7028f0..2a2c57e 100644 --- a/internal/service/ContentService.go +++ b/internal/service/ContentService.go @@ -1,6 +1,7 @@ package service import ( + "blog/internal/consts" "blog/internal/model/vo" "blog/third_party/database" "context" @@ -15,12 +16,12 @@ var ContentService contentService func (*contentService) InitContentData() { var contentSlice []vo.CommonContent - result := database.GormTemplate.Table("common_contents").Where("state = ?", "publish").Find(&contentSlice) + result := database.GormTemplate.Table("common_contents").Where("state = ?", consts.CONTENT_STATE_PUBLISH).Find(&contentSlice) log.Println("大文本初始化数据加载量:", result.RowsAffected) ctx := context.Background() for _, content := range contentSlice { - database.RedisTemplate.Set(ctx, "blog:content:"+content.RelId, content.Content, time.Duration(0)) + database.RedisTemplate.Set(ctx, consts.REDIS_BLOG_CONTENT+content.RelId, content.Content, time.Duration(0)) } } @@ -28,7 +29,7 @@ func (*contentService) InitContentData() { func (*contentService) GetContentByCache(relId string) string { ctx := context.Background() var content string - database.RedisTemplate.Get(ctx, "blog:content:"+relId).Scan(&content) + database.RedisTemplate.Get(ctx, consts.REDIS_BLOG_CONTENT+relId).Scan(&content) return content } diff --git a/internal/service/DinaryService.go b/internal/service/DinaryService.go index 9efc2c8..3944cc3 100644 --- a/internal/service/DinaryService.go +++ b/internal/service/DinaryService.go @@ -1,6 +1,7 @@ package service import ( + "blog/internal/consts" "blog/internal/model/blog" "blog/third_party/database" "context" @@ -23,7 +24,7 @@ func (*diaryService) InitDiaryData() { for _, diary := range diarySlice { // log.Println(article) publishTime := diary.PublishTime - err := database.RedisTemplate.ZAdd(ctx, "blog:diary:latest", redis.Z{Score: float64(publishTime), Member: &diary}).Err() + err := database.RedisTemplate.ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(publishTime), Member: &diary}).Err() if err != nil { log.Println(err) } diff --git a/internal/service/FileService.go b/internal/service/FileService.go index e77adf9..a17013c 100644 --- a/internal/service/FileService.go +++ b/internal/service/FileService.go @@ -1,9 +1,12 @@ package service import ( + "blog/internal/consts" + "blog/internal/model/admin" "blog/internal/model/vo" "blog/third_party/database" "context" + "log" "time" ) @@ -12,15 +15,46 @@ type fileService struct { var FileService fileService -func (*fileService) GetFile(relId string) []byte { +func (*fileService) GetFile(id string) (vo.CommonFiles, error) { ctx := context.Background() - key := "blog:file:" + relId - bytes, err := database.RedisTemplate.Get(ctx, key).Bytes() - if err != nil { - var file vo.CommonFiles - database.GormTemplate.Table("common_files").Where("id = ?", relId).First(&file) + var file vo.CommonFiles + var bytes []byte + err := database.RedisTemplate.Get(ctx, consts.REDIS_FILE+id).Scan(&file) + //如果缓存不存在,则查数据库并存入Redis + if err != nil || file.Id == "" { + database.GormTemplate.Table("common_files").Where("id = ?", id).First(&file) bytes = file.Data - database.RedisTemplate.Set(ctx, key, bytes, time.Duration(0)) + err = database.RedisTemplate.Set(ctx, consts.REDIS_FILE+id, &file, time.Duration(0)).Err() + if err != nil { + log.Println(err) + } + err = database.RedisTemplate.Set(ctx, consts.REDIS_FILE_BYTES+id, bytes, time.Duration(0)).Err() + if err != nil { + log.Println(err) + } + return file, nil } - return bytes + bytes, err = database.RedisTemplate.Get(ctx, consts.REDIS_FILE_BYTES+id).Bytes() + file.Data = bytes + return file, err +} + +func (*fileService) PageSysFiles(page int, itemsPerPage int) vo.Page[admin.SysFile] { + var content []admin.SysFile + var totalElements int64 + database.GormTemplate.Table("common_files").Count(&totalElements) + database.GormTemplate.Table("common_files"). + Where("del != ?", 1). + Offset((page - 1) * itemsPerPage). + Limit(itemsPerPage). + Order("create_time DESC"). + Find(&content) + + pre := int(totalElements) % itemsPerPage + if pre > 0 { + pre = 1 + } + var totalPages int = int(totalElements)/itemsPerPage + pre + + return vo.Page[admin.SysFile]{TotalElements: totalElements, TotalPages: totalPages, Number: totalPages, Content: content} } diff --git a/main.go b/main.go index 91adb2a..dd8d0d5 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,8 @@ import ( // func main() { // i := time.Now().UnixMilli() // log.Println(i) +// b, _ := bcrypt.GenerateFromPassword([]byte("123456"), bcrypt.DefaultCost) +// log.Println(string(b)) // } func main() { diff --git a/template/admin/article/editor/tinymce.html b/template/admin/article/editor/tinymce.html index 7dcb58e..df41acf 100644 --- a/template/admin/article/editor/tinymce.html +++ b/template/admin/article/editor/tinymce.html @@ -1,11 +1,12 @@ + Admin Console - - - + + + @@ -15,8 +16,9 @@ + -
+
+ \ No newline at end of file diff --git a/template/admin/file/index.html b/template/admin/file/index.html new file mode 100644 index 0000000..5f2b8b2 --- /dev/null +++ b/template/admin/file/index.html @@ -0,0 +1,201 @@ + + + + + + Admin Console + + + + + + + + + + + + + + + +
+ + + + + + + \ No newline at end of file