后台增加日记文章列表删除功能,迁移部分启动加载的代码

This commit is contained in:
sysnix 2024-03-04 23:30:08 +08:00
parent c64f52ed19
commit 25a7dea858
39 changed files with 722 additions and 390 deletions

71
bootstrap/InitData.go Normal file
View File

@ -0,0 +1,71 @@
package bootstrap
// import (
// "Blog/internal/client"
// "Blog/internal/consts"
// "Blog/internal/model"
// "Blog/internal/repository"
// "context"
// "time"
// red "github.com/redis/go-redis/v9"
// "github.com/sirupsen/logrus"
// )
// func InitData() {
// initArticleData()
// // initDiaryData()
// // initContentData()
// // initViewRecordData()
// }
// func initArticleData() {
// var slices []model.BlogArticle = repository.ArticleRep.FindList(nil, "state = ?", consts.ARTICLE_STATE_PUBLISH)
// logrus.Info("文章初始化数据加载量:", len(slices))
// ctx := context.Background()
// for _, article := range slices {
// // logrus.Info(article)
// publishTime := article.PublishTime
// err := client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, red.Z{Score: float64(publishTime), Member: &article}).Err()
// if err != nil {
// logrus.Info(err)
// }
// }
// }
// func initDiaryData() {
// // bd := repository.DiaryRepository.BaseRep().Get("")
// var slices []model.BlogDiary = repository.DiaryRep.FindList(nil)
// // result := repository.DiaryRepository.DB.Gorm.Table(consts.TABLE_BLOG_DIARY).Find(&diarySlice)
// logrus.Info("日记初始化数据加载量:", len(slices))
// ctx := context.Background()
// for _, diary := range slices {
// // logrus.Info(article)
// publishTime := diary.PublishTime
// err := client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, red.Z{Score: float64(publishTime), Member: &diary}).Err()
// if err != nil {
// logrus.Info(err)
// }
// }
// }
// func initContentData() {
// var slices []model.BlogTextContent = repository.TextContentRep.FindList(nil, "state = ?", consts.CONTENT_STATE_PUBLISH)
// logrus.Info("大文本初始化数据加载量:", len(slices))
// for _, content := range slices {
// client.RedisClient().Set(context.Background(), consts.REDIS_BLOG_CONTENT+content.RelId, &content, time.Duration(0))
// }
// }
// func initViewRecordData() {
// type viewRecord struct {
// RelId string
// Counts int
// }
// var slices []viewRecord
// repository.ViewRecordRep().Table(consts.TABLE_BLOG_VIEW_RECORD).Select("rel_id ,count(1) counts").Group("rel_id").Find(&slices)
// logrus.Info("点击量初始化数据加载量:", len(slices))
// for _, val := range slices {
// client.RedisClient().HSet(context.Background(), consts.REDIS_BLOG_VIEW_RECORD, map[string]any{val.RelId: val.Counts})
// }
// }

View File

@ -1,70 +0,0 @@
package bootstrap
import (
"os"
"sync"
sqliteDB "github.com/glebarez/sqlite"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
var BlogDB *DB
var FileDB *DB
type DB struct {
Gorm *gorm.DB
Mutex *sync.RWMutex
}
// sqlite无法同时多个线程写入需要上锁保护读操作无需考虑
func (db *DB) WGorm(txFunc func(tx *gorm.DB) error) error {
db.Mutex.Lock()
err := db.Gorm.Transaction(txFunc)
db.Mutex.Unlock()
return err
}
func initBlogGorm() {
path := Config.Database.Sqlite.BlogPath
logrus.Info("数据库文件位置:", path)
_, err := os.Stat(path)
if err != nil || os.IsNotExist(err) {
panic("SQLite数据库文件不存在!")
}
orm, err := gorm.Open(sqliteDB.Open(path), &gorm.Config{})
if err != nil {
panic("BlogGorm初始化异常!" + err.Error())
}
// orm.Exec("PRAGMA journal_mode=WAL;")
BlogDB = &DB{
Gorm: orm,
Mutex: &sync.RWMutex{},
}
logrus.Info("SQLite连接成功,BlogGorm初始化完成")
}
func initFileGorm() {
path := Config.Database.Sqlite.FilePath
logrus.Info("数据库文件位置:", path)
// path := "./sqlite.db"
_, err := os.Stat(path)
if err != nil || os.IsNotExist(err) {
panic("sqlite数据库文件不存在!")
}
orm, err := gorm.Open(sqliteDB.Open(path), &gorm.Config{})
if err != nil {
panic("Gorm初始化异常!" + err.Error())
}
// orm.Exec("PRAGMA journal_mode=WAL;")
FileDB = &DB{
Gorm: orm,
Mutex: &sync.RWMutex{},
}
logrus.Info("SQLite连接成功,FileGorm初始化完成")
}

View File

@ -1,25 +0,0 @@
package bootstrap
import (
"Blog/internal/client"
"context"
red "github.com/redis/go-redis/v9"
"github.com/sirupsen/logrus"
)
func initRedis() {
addr := Config.Database.Redis.Addr
db := Config.Database.Redis.Db
client.RedisClient = red.NewClient(&red.Options{
Addr: addr,
DB: db, // 默认DB 0
})
ctx := context.Background()
sc := client.RedisClient.Ping(ctx)
pong := sc.Val()
if pong == "PONG" {
logrus.Info("Redis连接成功")
client.RedisClient.FlushDB(ctx)
}
}

View File

@ -1,13 +1,5 @@
package bootstrap
import (
"io"
"os"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
var Config bootstrap
type bootstrap struct {
@ -19,6 +11,7 @@ type bootstrap struct {
// =========================================================
type iris struct {
Port int `yaml:"port"`
Session session `yaml:"session"`
}
@ -47,44 +40,3 @@ type sqlite struct {
BlogPath string `yaml:"blogPath"`
FilePath string `yaml:"filePath"`
}
//=========================================================
func init() {
//日志文件位置
f, err := os.OpenFile("./Iris.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
panic("日志文件错误")
}
//控制台和日志文件都输出
iw := io.MultiWriter(f, os.Stdout)
//日志设置
// logrus.SetFormatter(log.Ldate | log.Ltime | log.Lmicroseconds | log.Ltime | log.Llongfile)
logrus.SetOutput(iw)
logrus.SetFormatter(&logrus.TextFormatter{
ForceColors: true,
FullTimestamp: true,
TimestampFormat: "2006-01-02 15:04:05.000",
})
logrus.SetReportCaller(true)
logrus.Info("init bootstrap")
b, err := os.ReadFile("conf/bootstrap.yaml")
if err != nil {
panic(err)
}
err3 := yaml.Unmarshal(b, &Config)
if err3 != nil {
panic(err3)
}
profile := Config.Profile
logrus.Info("当前Profile:", profile)
if profile == "dev" {
logrus.SetLevel(logrus.DebugLevel)
}
//初始化Gorm相关数据的配置
initBlogGorm()
initFileGorm()
initRedis()
}

View File

@ -1,7 +1,8 @@
profile: dev
iris:
port: 8080
session:
address: localhost:6379
address: 192.168.0.5:6379
db: 0
prefix: "iris:session:"
expires: 10
@ -10,5 +11,5 @@ database:
blogPath: ./db_blog.db
filePath: ./db_file.db
redis:
addr: localhost:6379
addr: 192.168.0.5:6379
db: 0

15
conf/bootstrap-prod.yaml Normal file
View File

@ -0,0 +1,15 @@
profile: dev
iris:
port: 8088
session:
address: 192.168.0.5:6379
db: 0
prefix: "iris:session:"
expires: 10
database:
sqlite:
blogPath: ./db_blog.db
filePath: ./db_file.db
redis:
addr: 192.168.0.5:6379
db: 0

View File

@ -25,7 +25,7 @@ func init() {
logrus.Info("IP:", record.IpAddr, "点击了:", record.Title)
relId := record.RelId
record.Id = uuid.NewString()
err := repository.ViewRecordRepository.WGorm(func(tx *gorm.DB) error {
err := repository.ViewRecordRep().WGorm(func(tx *gorm.DB) error {
err := tx.Table(consts.TABLE_BLOG_VIEW_RECORD).Create(&record).Error
return err
})
@ -34,7 +34,7 @@ func init() {
logrus.Error("流量记录保存失败")
}
err = client.RedisClient.HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, relId, 1).Err()
err = client.RedisClient().HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, relId, 1).Err()
if err != nil {
logrus.Error(err)
logrus.Error("流量记录写入Redis失败:", record.Title)

View File

@ -0,0 +1,87 @@
package client
import (
"Blog/bootstrap"
"os"
"sync"
"github.com/glebarez/sqlite"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
var fileGorm *DB
var blogGorm *DB
var gormInitMutex *sync.Mutex = &sync.Mutex{}
type DB struct {
*gorm.DB
Mutex *sync.RWMutex
}
// sqlite无法同时多个线程写入需要上锁保护读操作无需考虑
func (db *DB) WGorm(txFunc func(tx *gorm.DB) error) error {
db.Mutex.Lock()
err := db.Transaction(txFunc)
db.Mutex.Unlock()
return err
}
func BlogGormClient() *DB {
//为空就初始化
if blogGorm == nil {
gormInitMutex.Lock()
if blogGorm == nil {
path := bootstrap.Config.Database.Sqlite.BlogPath
logrus.Info("数据库文件位置:", path)
_, err := os.Stat(path)
if err != nil || os.IsNotExist(err) {
panic("SQLite数据库文件不存在!")
}
orm, err := gorm.Open(sqlite.Open(path), &gorm.Config{})
if err != nil {
panic("BlogGorm初始化异常!" + err.Error())
}
// orm.Exec("PRAGMA journal_mode=WAL;")
blogGorm = &DB{
DB: orm,
Mutex: &sync.RWMutex{},
}
logrus.Info("SQLite连接成功,BlogGorm初始化完成")
}
gormInitMutex.Unlock()
}
return blogGorm
}
func FileGormClient() *DB {
//为空就初始化
if fileGorm == nil {
gormInitMutex.Lock()
if fileGorm == nil {
path := bootstrap.Config.Database.Sqlite.FilePath
logrus.Info("数据库文件位置:", path)
// path := "./sqlite.db"
_, err := os.Stat(path)
if err != nil || os.IsNotExist(err) {
panic("sqlite数据库文件不存在!")
}
orm, err := gorm.Open(sqlite.Open(path), &gorm.Config{})
if err != nil {
panic("Gorm初始化异常!" + err.Error())
}
// orm.Exec("PRAGMA journal_mode=WAL;")
fileGorm = &DB{
DB: orm,
Mutex: &sync.RWMutex{},
}
logrus.Info("SQLite连接成功,FileGorm初始化完成")
}
gormInitMutex.Unlock()
}
return fileGorm
}

View File

@ -1,7 +1,36 @@
package client
import (
"Blog/bootstrap"
"context"
"sync"
"github.com/redis/go-redis/v9"
"github.com/sirupsen/logrus"
)
var RedisClient *redis.Client
var redisClient *redis.Client
var redisInitMutex *sync.Mutex = &sync.Mutex{}
func RedisClient() *redis.Client {
if redisClient == nil {
redisInitMutex.Lock()
if redisClient == nil {
addr := bootstrap.Config.Database.Redis.Addr
db := bootstrap.Config.Database.Redis.Db
redisClient = redis.NewClient(&redis.Options{
Addr: addr,
DB: db, // 默认DB 0
})
ctx := context.Background()
sc := redisClient.Ping(ctx)
pong := sc.Val()
if pong == "PONG" {
logrus.Info("Redis连接成功")
redisClient.FlushDB(ctx)
}
}
redisInitMutex.Unlock()
}
return redisClient
}

1
internal/config/db.go Normal file
View File

@ -0,0 +1 @@
package config

1
internal/config/redis.go Normal file
View File

@ -0,0 +1 @@
package config

View File

@ -25,7 +25,7 @@ func (c *VersionController) Get() {
func (ctrl *VersionController) GetList() {
var versions []model.SysVersion
repository.VersionRepository.Table(consts.TABLE_SYS_VERSION).Order("create_time Desc").Find(&versions)
repository.VersionRepository().Table(consts.TABLE_SYS_VERSION).Order("create_time Desc").Find(&versions)
service.VersionService.FindVersions()
ctrl.Ctx.JSON(result.Ok(versions))
}
@ -43,7 +43,7 @@ func (ctrl *VersionController) PostSubmit() {
version.CreateTime = now
version.State = "1"
version.Del = 0
err := repository.VersionRepository.Table(consts.TABLE_SYS_VERSION).Create(&version).Error
err := repository.VersionRepository().Table(consts.TABLE_SYS_VERSION).Create(&version).Error
if err != nil {
ctrl.Ctx.JSON(result.Error("添加版本信息失败"))

View File

@ -1,13 +1,21 @@
package adm_controller
import (
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
"Blog/internal/model/result"
"Blog/internal/repository"
"Blog/internal/service"
"Blog/internal/utils"
"context"
"net/http"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/mvc"
"github.com/kataras/iris/v12/sessions"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
/*
@ -43,3 +51,45 @@ func (ctrl *DiaryController) PostSubmit() {
ctrl.Ctx.JSON(result.OkMsg("发布成功", nil))
}
func (ctrl *DiaryController) DelDiary() {
id := ctrl.Ctx.Params().Get("id")
if id == "" {
ctrl.Ctx.JSON(result.Error("ID为空"))
return
}
logrus.Info("删除日记==>", id)
ctx := context.Background()
err := repository.DiaryRepository().WGorm(func(tx *gorm.DB) error {
var txErr error
txErr = tx.Table(consts.TABLE_BLOG_DIARY).Unscoped().Delete(&model.BlogDiary{Id: id}).Error
if txErr != nil {
return txErr
}
txErr = tx.Table(consts.TABLE_BLOG_TEXT_CONTENT).Unscoped().Where("rel_id = ?", id).Delete(&model.BlogTextContent{}).Error
if txErr != nil {
return txErr
}
client.RedisClient().Del(ctx, consts.REDIS_BLOG_DIARY+id, consts.REDIS_BLOG_CONTENT+id).Err()
return txErr
})
if err == nil {
service.DiaryService.RefreshLatest()
}
if err != nil {
ctrl.Ctx.JSON(result.Error("删除失败"))
}
ctrl.Ctx.JSON(result.OkMsg("删除完成", nil))
}
func (ctrl *DiaryController) BeforeActivation(activation mvc.BeforeActivation) {
// logrus.Info("before")
activation.Handle(http.MethodDelete, "/del/{id}", "DelDiary")
}
func (ctrl *DiaryController) AfterActivation(activation mvc.AfterActivation) {
// logrus.Info("after")
}

View File

@ -86,12 +86,12 @@ func (ctrl *FileController) DelFile() {
return
}
ctx := context.Background()
err := repository.FileRepository.WGorm(func(tx *gorm.DB) error {
err := repository.FileRepository().WGorm(func(tx *gorm.DB) error {
txErr := tx.Table(consts.TABLE_UPLOAD_FILE).Delete(&model.UploadFile{Id: id}).Error
if txErr != nil {
return txErr
}
client.RedisClient.Del(ctx, consts.REDIS_FILE+id, consts.REDIS_FILE_BYTES+id).Err()
client.RedisClient().Del(ctx, consts.REDIS_FILE+id, consts.REDIS_FILE_BYTES+id).Err()
return txErr
})

View File

@ -95,7 +95,7 @@ func (ctrl *LoginController) Post() {
// logrus.Info(sql)
// result := repository.UserRepository.DB.Gorm.Table(consts.TABLE_SYS_USER).Where("username = ?", loginUser.Username).First(&user)
user := repository.UserRepository.FindOne("username = ?", loginUser.Username)
user := repository.UserRepository().FindOne("username = ?", loginUser.Username)
if user == nil {
ctrl.Ctx.ViewData("user", loginUser)
ctrl.Ctx.ViewData("errorMsg", "账号不存在")

View File

@ -47,7 +47,7 @@ func (ctrl *ArticleController) GetLatest() {
// ctx := context.Background()
// var slices []model.BlogArticle
// err := client.RedisClient.ZRevRange(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, 0, 10).ScanSlice(&slices)
// err := client.RedisClient().ZRevRange(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, 0, 10).ScanSlice(&slices)
// if err != nil {
// logrus.Info(err)
// ctrl.Ctx.JSON(result.Error("加载错误"))
@ -56,7 +56,7 @@ func (ctrl *ArticleController) GetLatest() {
// for i := range slices {
// article := &slices[i]
// id := article.Id
// viewRecord, _ := client.RedisClient.HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int()
// viewRecord, _ := client.RedisClient().HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int()
// article.ViewRecord = viewRecord
// }

View File

@ -25,7 +25,7 @@ func (ctrl *DiaryController) Get() {
func (ctrl *DiaryController) GetLatest() {
ctx := context.Background()
var slices []model.BlogDiary
err := client.RedisClient.ZRevRange(ctx, consts.REDIS_BLOG_DIARY_LATEST, 0, 2).ScanSlice(&slices)
err := client.RedisClient().ZRevRange(ctx, consts.REDIS_BLOG_DIARY_LATEST, 0, 2).ScanSlice(&slices)
if err != nil {
logrus.Info(err)
ctrl.Ctx.JSON(result.Error("加载错误"))
@ -37,14 +37,16 @@ func (ctrl *DiaryController) GetLatest() {
ptr := &slices[i]
textContent := service.TextContentService.GetContent(item.Id)
// ptr.Content = content
if textContent != nil {
var vo = struct {
Id string `json:"id"`
Images string `json:"images"`
PublishTime int64 `json:"publishTime"`
Content string `json:"content"`
}{Id: ptr.Id, Images: ptr.Images, PublishTime: ptr.PublishTime, Content: textContent.Content}
ret = append(ret, vo)
var vo = struct {
Id string `json:"id"`
Images string `json:"images"`
PublishTime int64 `json:"publishTime"`
Content string `json:"content"`
}{Id: ptr.Id, Images: ptr.Images, PublishTime: ptr.PublishTime, Content: textContent.Content}
ret = append(ret, vo)
}
}
ctrl.Ctx.JSON(result.Ok(ret))

View File

@ -6,6 +6,7 @@ import (
"Blog/internal/controller/cli_controller"
"Blog/internal/middleware"
"Blog/internal/utils"
"fmt"
"net/http"
"time"
@ -16,7 +17,7 @@ import (
"github.com/sirupsen/logrus"
)
func Router() {
func Router(port int) {
profile := bootstrap.Config.Profile
//
app := iris.Default()
@ -80,7 +81,7 @@ func Router() {
})
app.Listen("localhost:8080")
app.Listen(fmt.Sprintf(":%d", port))
}

View File

@ -4,7 +4,7 @@ import "encoding/json"
type BlogTextContent struct {
Id string `json:"id" gorm:"primary_key"`
RelId string `json:"relId"`
RelId string `json:"relId" gorm:"rel_id"`
Content string `json:"content"`
State string `json:"state"`
}

View File

@ -1,25 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var ArticleRepository *articleRepository = newArticleRepository()
var articleRep *articleRepository
func ArticleRepository() *articleRepository {
if articleRep == nil {
articleRep = &articleRepository{
&BaseRep[model.BlogArticle]{
DB: client.BlogGormClient(),
TableName: consts.TABLE_BLOG_ARTICLE,
},
}
}
return articleRep
}
type articleRepository struct {
*baseRep[model.BlogArticle]
// DB *bootstrap.DB
}
func newArticleRepository() *articleRepository {
return &articleRepository{
&baseRep[model.BlogArticle]{
DB: bootstrap.BlogDB.Gorm,
Mutex: bootstrap.BlogDB.Mutex,
TableName: consts.TABLE_BLOG_ARTICLE,
},
}
// return &articleRepository{DB: bootstrap.BlogDB}
*BaseRep[model.BlogArticle]
}

View File

@ -1,26 +1,25 @@
package repository
import (
"sync"
"Blog/internal/client"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
type baseRep[T any] struct {
*gorm.DB
Mutex *sync.RWMutex
type BaseRep[T any] struct {
*client.DB
TableName string
}
func (rep *baseRep[T]) WGorm(txFunc func(tx *gorm.DB) error) error {
rep.Mutex.Lock()
err := rep.Transaction(txFunc)
rep.Mutex.Unlock()
func (rep *BaseRep[T]) WGorm(txFunc func(tx *gorm.DB) error) error {
rep.DB.Mutex.Lock()
err := rep.DB.Transaction(txFunc)
rep.DB.Mutex.Unlock()
return err
}
func (repository *baseRep[T]) GetById(id string) (ret *T) {
func (repository *BaseRep[T]) GetById(id string) (ret *T) {
ret = new(T)
sql := repository.ToSQL(func(tx *gorm.DB) *gorm.DB {
return tx.Table(repository.TableName).First(ret, "id = ?", id)
@ -35,7 +34,7 @@ func (repository *baseRep[T]) GetById(id string) (ret *T) {
return ret
}
func (repository *baseRep[T]) FindList(order interface{}, conds ...interface{}) (ret []T) {
func (repository *BaseRep[T]) FindList(order interface{}, conds ...interface{}) (ret []T) {
sql := repository.ToSQL(func(tx *gorm.DB) *gorm.DB {
return tx.Table(repository.TableName).Find(&ret, conds...)
})
@ -52,7 +51,7 @@ func (repository *baseRep[T]) FindList(order interface{}, conds ...interface{})
return ret
}
func (repository *baseRep[T]) FindOne(conds ...interface{}) (ret *T) {
func (repository *BaseRep[T]) FindOne(conds ...interface{}) (ret *T) {
ret = new(T)
sql := repository.ToSQL(func(tx *gorm.DB) *gorm.DB {
return tx.Table(repository.TableName).First(ret, conds...)

View File

@ -1,23 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var DiaryRepository *diaryRepository = newDiaryRepository()
var diaryRep *diaryRepository
func DiaryRepository() *diaryRepository {
if diaryRep == nil {
diaryRep = &diaryRepository{
&BaseRep[model.BlogDiary]{
DB: client.BlogGormClient(),
TableName: consts.TABLE_BLOG_DIARY,
},
}
}
return diaryRep
}
type diaryRepository struct {
*baseRep[model.BlogDiary]
}
func newDiaryRepository() *diaryRepository {
return &diaryRepository{
&baseRep[model.BlogDiary]{
DB: bootstrap.BlogDB.Gorm,
Mutex: bootstrap.BlogDB.Mutex,
TableName: consts.TABLE_BLOG_DIARY,
},
}
*BaseRep[model.BlogDiary]
}

View File

@ -1,23 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var FileRepository *fileRepository = newFileRepository()
var fileRep *fileRepository
func FileRepository() *fileRepository {
if fileRep == nil {
fileRep = &fileRepository{
&BaseRep[model.UploadFile]{
DB: client.FileGormClient(),
TableName: consts.TABLE_UPLOAD_FILE,
},
}
}
return fileRep
}
type fileRepository struct {
*baseRep[model.UploadFile]
}
func newFileRepository() *fileRepository {
return &fileRepository{
&baseRep[model.UploadFile]{
DB: bootstrap.FileDB.Gorm,
Mutex: bootstrap.FileDB.Mutex,
TableName: consts.TABLE_UPLOAD_FILE,
},
}
*BaseRep[model.UploadFile]
}

View File

@ -1,23 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var TextContentRepository *textContentRepository = newTextContentRepository()
var textContentRep *textContentRepository
func TextContentRepository() *textContentRepository {
if textContentRep == nil {
textContentRep = &textContentRepository{
&BaseRep[model.BlogTextContent]{
DB: client.BlogGormClient(),
TableName: consts.TABLE_BLOG_TEXT_CONTENT,
},
}
}
return textContentRep
}
type textContentRepository struct {
*baseRep[model.BlogTextContent]
}
func newTextContentRepository() *textContentRepository {
return &textContentRepository{
&baseRep[model.BlogTextContent]{
DB: bootstrap.BlogDB.Gorm,
Mutex: bootstrap.BlogDB.Mutex,
TableName: consts.TABLE_BLOG_TEXT_CONTENT,
},
}
*BaseRep[model.BlogTextContent]
}

View File

@ -1,23 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var UserRepository *userRepository = newUserRepository()
var userRep *userRepository
func UserRepository() *userRepository {
if userRep == nil {
userRep = &userRepository{
&BaseRep[model.SysUser]{
DB: client.BlogGormClient(),
TableName: consts.TABLE_SYS_USER,
},
}
}
return userRep
}
type userRepository struct {
*baseRep[model.SysUser]
}
func newUserRepository() *userRepository {
return &userRepository{
&baseRep[model.SysUser]{
DB: bootstrap.BlogDB.Gorm,
Mutex: bootstrap.BlogDB.Mutex,
TableName: consts.TABLE_SYS_USER,
},
}
*BaseRep[model.SysUser]
}

View File

@ -1,23 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var VersionRepository *versionRepository = newVersionRepository()
var versionRep *versionRepository
func VersionRepository() *versionRepository {
if versionRep == nil {
versionRep = &versionRepository{
&BaseRep[model.SysVersion]{
DB: client.BlogGormClient(),
TableName: consts.TABLE_SYS_VERSION,
},
}
}
return versionRep
}
type versionRepository struct {
*baseRep[model.SysVersion]
}
func newVersionRepository() *versionRepository {
return &versionRepository{
&baseRep[model.SysVersion]{
DB: bootstrap.BlogDB.Gorm,
Mutex: bootstrap.BlogDB.Mutex,
TableName: consts.TABLE_SYS_VERSION,
},
}
*BaseRep[model.SysVersion]
}

View File

@ -1,23 +1,25 @@
package repository
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/model"
)
var ViewRecordRepository *viewRecordRepository = newViewRecordRepository()
var viewRecordRep *ViewRecordRepository
type viewRecordRepository struct {
*baseRep[model.ViewRecord]
}
func newViewRecordRepository() *viewRecordRepository {
return &viewRecordRepository{
&baseRep[model.ViewRecord]{
DB: bootstrap.BlogDB.Gorm,
Mutex: bootstrap.BlogDB.Mutex,
TableName: consts.TABLE_BLOG_VIEW_RECORD,
},
func ViewRecordRep() *ViewRecordRepository {
if viewRecordRep == nil {
viewRecordRep = &ViewRecordRepository{
&BaseRep[model.ViewRecord]{
DB: client.BlogGormClient(),
TableName: consts.TABLE_BLOG_VIEW_RECORD,
},
}
}
return viewRecordRep
}
type ViewRecordRepository struct {
*BaseRep[model.ViewRecord]
}

View File

@ -21,22 +21,8 @@ var ArticleService *articleService = newArticleService()
type articleService struct {
}
func initArticleData() {
var slices []model.BlogArticle = repository.ArticleRepository.FindList(nil, "state = ?", consts.ARTICLE_STATE_PUBLISH)
logrus.Info("文章初始化数据加载量:", len(slices))
ctx := context.Background()
for _, article := range slices {
// logrus.Info(article)
publishTime := article.PublishTime
err := client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
if err != nil {
logrus.Info(err)
}
}
}
func newArticleService() *articleService {
go initArticleData()
// go initArticleData()
return &articleService{}
}
@ -45,12 +31,12 @@ func newArticleService() *articleService {
func (*articleService) GetArticle(id string) *model.BlogArticle {
var ret *model.BlogArticle = &model.BlogArticle{}
key := consts.REDIS_BLOG_ARTICLE + id
err := client.RedisClient.Get(context.Background(), key).Scan(ret)
err := client.RedisClient().Get(context.Background(), key).Scan(ret)
if err != nil {
logrus.Infoln(id, "文章的缓存不存在,读取数据库")
ret = repository.ArticleRepository.GetById(id)
ret = repository.ArticleRepository().GetById(id)
if ret != nil {
client.RedisClient.Set(context.Background(), key, ret, time.Duration(0))
client.RedisClient().Set(context.Background(), key, ret, time.Duration(0))
}
}
return ret
@ -60,16 +46,16 @@ func (*articleService) GetLatest() []model.BlogArticle {
ctx := context.Background()
var slices []model.BlogArticle
err := client.RedisClient.ZRevRange(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, 0, 10).ScanSlice(&slices)
err := client.RedisClient().ZRevRange(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, 0, 10).ScanSlice(&slices)
// if err != nil || len(slices) == 0 {
// result := repository.ArticleRepository.Where("state = ?", consts.ARTICLE_STATE_PUBLISH).Order("publish_time DESC").Find(&slices)
// logrus.Info("文章初始化数据加载量:", result.RowsAffected)
// ctx := context.Background()
// client.RedisClient.Del(ctx, consts.REDIS_BLOG_ARTICLE_LATEST)
// client.RedisClient().Del(ctx, consts.REDIS_BLOG_ARTICLE_LATEST)
// for _, article := range slices {
// // logrus.Info(article)
// publishTime := article.PublishTime
// err := client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
// err := client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
// if err != nil {
// logrus.Info(err)
// }
@ -88,8 +74,8 @@ func (*articleService) PageArticle(page int, itemsPerPage int) model.Page[any] {
var slice []model.BlogArticle
var totalElements int64
ctx := context.Background()
repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Count(&totalElements)
repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).
repository.ArticleRepository().Table(consts.TABLE_BLOG_ARTICLE).Count(&totalElements)
repository.ArticleRepository().Table(consts.TABLE_BLOG_ARTICLE).
Where("del != ?", 1).
Offset((page - 1) * itemsPerPage).
Limit(itemsPerPage).
@ -100,7 +86,7 @@ func (*articleService) PageArticle(page int, itemsPerPage int) model.Page[any] {
for _, v := range slice {
id := v.Id
view, _ := client.RedisClient.HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int64()
view, _ := client.RedisClient().HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int64()
// content[i].View = view
var vo = struct {
model.BlogArticle
@ -129,7 +115,7 @@ func (*articleService) CreateArticle(articel *model.BlogArticle) (string, error)
articel.Del = 0
articel.State = consts.ARTICLE_STATE_DRAFT
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
err := repository.ArticleRepository().WGorm(func(tx *gorm.DB) error {
contentId := uuid.NewString()
content := articel.Content
commonContent := model.BlogTextContent{Id: contentId, RelId: articleId, Content: content, State: consts.CONTENT_STATE_DOWN}
@ -150,7 +136,7 @@ func (*articleService) UpdateArticle(articel *model.BlogArticle) (string, error)
time := time.Now().UnixMilli()
articleId := articel.Id
articel.UpdateTime = time
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
err := repository.ArticleRepository().WGorm(func(tx *gorm.DB) error {
//更新Article
tx.Table(consts.TABLE_BLOG_ARTICLE).Updates(articel)
@ -168,7 +154,7 @@ func (*articleService) PublishArticle(id string) error {
// var article model.BlogArticle
// err := repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).First(&article).Error
article := repository.ArticleRepository.GetById(id)
article := repository.ArticleRepository().GetById(id)
if article == nil {
return errors.New("不存在该文章")
}
@ -182,7 +168,7 @@ func (*articleService) PublishArticle(id string) error {
}
article.State = consts.ARTICLE_STATE_PUBLISH
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
err := repository.ArticleRepository().WGorm(func(tx *gorm.DB) error {
var txErr error = tx.Table(consts.TABLE_BLOG_ARTICLE).Updates(&article).Error
if txErr != nil {
return errors.New("文章更新错误")
@ -198,11 +184,11 @@ func (*articleService) PublishArticle(id string) error {
}
ctx := context.Background()
txErr = client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
txErr = client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
if txErr != nil {
return errors.New("缓存错误")
}
txErr = client.RedisClient.Set(ctx, consts.REDIS_BLOG_CONTENT+id, content.Content, time.Duration(0)).Err()
txErr = client.RedisClient().Set(ctx, consts.REDIS_BLOG_CONTENT+id, content.Content, time.Duration(0)).Err()
return txErr
})
@ -214,7 +200,7 @@ func (*articleService) PublishArticle(id string) error {
func (*articleService) UnPublishArticle(id string) error {
// var article model.BlogArticle
// err := repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).First(&article).Error
article := repository.ArticleRepository.GetById(id)
article := repository.ArticleRepository().GetById(id)
if article == nil {
return errors.New("不存在该文章")
}
@ -223,19 +209,19 @@ func (*articleService) UnPublishArticle(id string) error {
return errors.New("撤下失败,文章状态不是已发布状态,无法撤下")
}
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
err := repository.ArticleRepository().WGorm(func(tx *gorm.DB) error {
var txErr error
ctx := context.Background()
txErr = client.RedisClient.ZRemRangeByScore(ctx, consts.REDIS_BLOG_ARTICLE_LATEST,
txErr = client.RedisClient().ZRemRangeByScore(ctx, consts.REDIS_BLOG_ARTICLE_LATEST,
strconv.FormatFloat(float64(article.PublishTime), 'E', -1, 64),
strconv.FormatFloat(float64(article.PublishTime), 'E', -1, 64),
).Err()
// txErr = client.RedisClient.ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
// txErr = client.RedisClient().ZAdd(ctx, "blog:article:latest", redis.Z{Score: float64(article.PublishTime), Member: &article}).Err()
if txErr != nil {
return errors.New("缓存错误")
}
txErr = client.RedisClient.Del(ctx, consts.REDIS_BLOG_CONTENT+id).Err()
txErr = client.RedisClient().Del(ctx, consts.REDIS_BLOG_CONTENT+id).Err()
if txErr != nil {
return errors.New("缓存错误")
}
@ -259,7 +245,7 @@ func (*articleService) UnPublishArticle(id string) error {
func (*articleService) DelArticle(id string) error {
// articel := ArticleService.GetAdminArticle(id)
// err := repository.ArticleRepository.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).First(&article).Error
err := repository.ArticleRepository.WGorm(func(tx *gorm.DB) error {
err := repository.ArticleRepository().WGorm(func(tx *gorm.DB) error {
txErr := tx.Table(consts.TABLE_BLOG_ARTICLE).Where("id = ?", id).UpdateColumn("del", 1).Error
return txErr
})

View File

@ -23,24 +23,8 @@ var DiaryService *diaryService = newDiaryService()
type diaryService struct {
}
func initDiaryData() {
// bd := repository.DiaryRepository.BaseRep().Get("")
var slices []model.BlogDiary = repository.DiaryRepository.FindList(nil)
// result := repository.DiaryRepository.DB.Gorm.Table(consts.TABLE_BLOG_DIARY).Find(&diarySlice)
logrus.Info("日记初始化数据加载量:", len(slices))
ctx := context.Background()
for _, diary := range slices {
// logrus.Info(article)
publishTime := diary.PublishTime
err := client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(publishTime), Member: &diary}).Err()
if err != nil {
logrus.Info(err)
}
}
}
func newDiaryService() *diaryService {
go initDiaryData()
// go initDiaryData()
return &diaryService{}
}
@ -87,7 +71,7 @@ func (*diaryService) SaveDiary(content string, createBy string, fileHeaders []*m
CreateTime: now,
CreateBy: createBy,
}
txErr := repository.DiaryRepository.WGorm(func(tx *gorm.DB) error {
txErr := repository.DiaryRepository().WGorm(func(tx *gorm.DB) error {
err := tx.Table(consts.TABLE_BLOG_DIARY).Create(&diary).Error
if err != nil {
@ -104,11 +88,11 @@ func (*diaryService) SaveDiary(content string, createBy string, fileHeaders []*m
return nil
}
err := client.RedisClient.ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(diary.PublishTime), Member: &diary}).Err()
err := client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(diary.PublishTime), Member: &diary}).Err()
if err != nil {
logrus.Error("日记写入Redis失败,", err)
}
err = client.RedisClient.Set(ctx, consts.REDIS_BLOG_CONTENT+diaryId, content, time.Duration(0)).Err()
err = client.RedisClient().Set(ctx, consts.REDIS_BLOG_CONTENT+diaryId, content, time.Duration(0)).Err()
if err != nil {
logrus.Error("日记文本写入Redis失败", err)
}
@ -147,3 +131,22 @@ func compressImg(fileHeader *multipart.FileHeader) []byte {
file.Read(bytes)
return bytes
}
func (*diaryService) RefreshLatest() {
var slices []model.BlogDiary = repository.DiaryRepository().FindList(nil)
logrus.Info("日记初始化数据加载量:", len(slices))
ctx := context.Background()
delErr := client.RedisClient().Del(ctx, consts.REDIS_BLOG_DIARY_LATEST).Err()
if delErr != nil {
logrus.Error("刷新最新日记失败,Err=>", delErr.Error())
return
}
for _, diary := range slices {
// logrus.Info(article)
publishTime := diary.PublishTime
err := client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_DIARY_LATEST, redis.Z{Score: float64(publishTime), Member: &diary}).Err()
if err != nil {
logrus.Info(err)
}
}
}

View File

@ -26,23 +26,23 @@ func (*fileService) GetFile(id string) (*model.UploadFile, error) {
ctx := context.Background()
var file *model.UploadFile = &model.UploadFile{}
var bytes []byte
err := client.RedisClient.Get(ctx, consts.REDIS_FILE+id).Scan(file)
err := client.RedisClient().Get(ctx, consts.REDIS_FILE+id).Scan(file)
//如果缓存不存在则查数据库并存入Redis
if err != nil || file.Id == "" {
// repository.FileRepository.Table(consts.TABLE_UPLOAD_FILE).Where("id = ?", id).First(&file)
file := repository.FileRepository.GetById(id)
file := repository.FileRepository().GetById(id)
bytes = file.Data
err = client.RedisClient.Set(ctx, consts.REDIS_FILE+id, file, time.Duration(0)).Err()
err = client.RedisClient().Set(ctx, consts.REDIS_FILE+id, file, time.Duration(0)).Err()
if err != nil {
logrus.Info(err)
}
err = client.RedisClient.Set(ctx, consts.REDIS_FILE_BYTES+id, bytes, time.Duration(0)).Err()
err = client.RedisClient().Set(ctx, consts.REDIS_FILE_BYTES+id, bytes, time.Duration(0)).Err()
if err != nil {
logrus.Info(err)
}
return file, nil
}
bytes, err = client.RedisClient.Get(ctx, consts.REDIS_FILE_BYTES+id).Bytes()
bytes, err = client.RedisClient().Get(ctx, consts.REDIS_FILE_BYTES+id).Bytes()
file.Data = bytes
return file, err
}
@ -50,8 +50,8 @@ func (*fileService) GetFile(id string) (*model.UploadFile, error) {
func (*fileService) PageFiles(page int, itemsPerPage int) model.Page[model.UploadFile] {
var content []model.UploadFile
var totalElements int64
repository.FileRepository.Table(consts.TABLE_UPLOAD_FILE).Count(&totalElements)
repository.FileRepository.Table(consts.TABLE_UPLOAD_FILE).
repository.FileRepository().Table(consts.TABLE_UPLOAD_FILE).Count(&totalElements)
repository.FileRepository().Table(consts.TABLE_UPLOAD_FILE).
Where("del != ?", 1).
Offset((page - 1) * itemsPerPage).
Limit(itemsPerPage).
@ -85,7 +85,7 @@ func (*fileService) SaveFile(fileName string, data []byte, uploader string) *mod
Del: 0,
}
err := repository.FileRepository.WGorm(func(tx *gorm.DB) error {
err := repository.FileRepository().WGorm(func(tx *gorm.DB) error {
err2 := tx.Table(consts.TABLE_UPLOAD_FILE).Create(file).Error
return err2
})

View File

@ -6,10 +6,8 @@ import (
"Blog/internal/model"
"Blog/internal/repository"
"context"
"time"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
@ -18,16 +16,8 @@ var TextContentService *textContentService = newTextContentService()
type textContentService struct {
}
func initContentData() {
var slices []model.BlogTextContent = repository.TextContentRepository.FindList(nil, "state = ?", consts.CONTENT_STATE_PUBLISH)
logrus.Info("大文本初始化数据加载量:", len(slices))
for _, content := range slices {
client.RedisClient.Set(context.Background(), consts.REDIS_BLOG_CONTENT+content.RelId, &content, time.Duration(0))
}
}
func newTextContentService() *textContentService {
go initContentData()
//go initContentData()
return &textContentService{}
}
@ -35,10 +25,10 @@ func newTextContentService() *textContentService {
func (*textContentService) GetContent(relId string) *model.BlogTextContent {
ctx := context.Background()
var content *model.BlogTextContent = &model.BlogTextContent{}
err := client.RedisClient.Get(ctx, consts.REDIS_BLOG_CONTENT+relId).Scan(content)
err := client.RedisClient().Get(ctx, consts.REDIS_BLOG_CONTENT+relId).Scan(content)
if err != nil {
// err = repository.TextContentRepository.Table(consts.TABLE_BLOG_TEXT_CONTENT).Where("rel_id = ?", relId).First(content).Error
content = repository.TextContentRepository.FindOne("rel_id = ?", relId)
content = repository.TextContentRepository().FindOne("rel_id = ?", relId)
}
return content
}
@ -46,7 +36,7 @@ func (*textContentService) GetContent(relId string) *model.BlogTextContent {
func (*textContentService) SaveContent(relId string, content string) *model.BlogTextContent {
cnt := model.BlogTextContent{Id: uuid.NewString(), RelId: relId, Content: content, State: consts.CONTENT_STATE_PUBLISH}
txErr := repository.TextContentRepository.WGorm(func(tx *gorm.DB) error {
txErr := repository.TextContentRepository().WGorm(func(tx *gorm.DB) error {
err := tx.Table(consts.TABLE_BLOG_TEXT_CONTENT).Create(cnt).Error
return err
})
@ -58,6 +48,6 @@ func (*textContentService) SaveContent(relId string, content string) *model.Blog
}
func (*textContentService) UpdataState(relId string, state string) error {
err := repository.TextContentRepository.Table(consts.TABLE_BLOG_TEXT_CONTENT).Where("rel_id = ?", relId).UpdateColumn("state", state).Error
err := repository.TextContentRepository().Table(consts.TABLE_BLOG_TEXT_CONTENT).Where("rel_id = ?", relId).UpdateColumn("state", state).Error
return err
}

View File

@ -5,8 +5,6 @@ import (
"Blog/internal/consts"
"Blog/internal/repository"
"context"
"github.com/sirupsen/logrus"
)
var ViewRecordService *viewRecordService = newViewRecordService()
@ -14,21 +12,8 @@ var ViewRecordService *viewRecordService = newViewRecordService()
type viewRecordService struct {
}
func initViewRecordData() {
type viewRecord struct {
RelId string
Counts int
}
var slices []viewRecord
repository.ViewRecordRepository.Table(consts.TABLE_BLOG_VIEW_RECORD).Select("rel_id ,count(1) counts").Group("rel_id").Find(&slices)
logrus.Info("点击量初始化数据加载量:", len(slices))
for _, val := range slices {
client.RedisClient.HSet(context.Background(), consts.REDIS_BLOG_VIEW_RECORD, map[string]any{val.RelId: val.Counts})
}
}
func newViewRecordService() *viewRecordService {
go initViewRecordData()
//go initViewRecordData()
return &viewRecordService{}
}
@ -36,21 +21,21 @@ func newViewRecordService() *viewRecordService {
func (*viewRecordService) GetRecord(id string) int64 {
var count int64 = 0
ctx := context.Background()
// exists := client.RedisClient.Exists(ctx, consts.REDIS_BLOG_VIEW_RECORD).Val()
exists := client.RedisClient.HExists(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Val()
// exists := client.RedisClient().Exists(ctx, consts.REDIS_BLOG_VIEW_RECORD).Val()
exists := client.RedisClient().HExists(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Val()
if exists {
i, err := client.RedisClient.HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int64()
i, err := client.RedisClient().HGet(ctx, consts.REDIS_BLOG_VIEW_RECORD, id).Int64()
if err != nil {
return i
}
}
err := repository.ViewRecordRepository.Table(consts.TABLE_BLOG_VIEW_RECORD).Where("rel_id = ?", id).Count(&count).Error
err := repository.ViewRecordRep().Table(consts.TABLE_BLOG_VIEW_RECORD).Where("rel_id = ?", id).Count(&count).Error
if err != nil {
return 0
}
err = client.RedisClient.HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, id, count).Err()
err = client.RedisClient().HIncrBy(ctx, consts.REDIS_BLOG_VIEW_RECORD, id, count).Err()
if err != nil {
return 0
}

105
main.go
View File

@ -1,24 +1,121 @@
package main
import (
"Blog/bootstrap"
"Blog/internal/client"
"Blog/internal/consts"
"Blog/internal/controller"
"Blog/internal/model"
"Blog/internal/repository"
"Blog/internal/service"
"context"
"flag"
"fmt"
"io"
"os"
"time"
"github.com/redis/go-redis/v9"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
func main() {
// test()
profile := flag.String("profile", "dev", "启动的配置文件")
flag.Parse()
inits(*profile)
runServer()
defer func() {
logrus.Info("程序结束,关闭资源")
// db.Close()
client.RedisClient.Close()
client.RedisClient().Close()
}()
}
func runServer() {
func inits(profile string) {
//日志文件位置
f, err := os.OpenFile("./Iris.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
panic("日志文件错误")
}
//控制台和日志文件都输出
iw := io.MultiWriter(f, os.Stdout)
//日志设置
// logrus.SetFormatter(log.Ldate | log.Ltime | log.Lmicroseconds | log.Ltime | log.Llongfile)
logrus.SetOutput(iw)
logrus.SetFormatter(&logrus.TextFormatter{
ForceColors: true,
FullTimestamp: true,
TimestampFormat: "2006-01-02 15:04:05.000",
})
logrus.SetReportCaller(true)
logrus.Info("init bootstrap")
filePath := fmt.Sprintf("conf/bootstrap-%v.yaml", profile)
logrus.Info("当前Profile文件位置:", filePath)
b, err := os.ReadFile(filePath)
if err != nil {
panic(err)
}
err3 := yaml.Unmarshal(b, &bootstrap.Config)
if err3 != nil {
panic(err3)
}
controller.Router()
// profileName := bootstrap.Config.Profile
logrus.Info("当前Profile:", profile)
if profile == "dev" {
logrus.SetLevel(logrus.DebugLevel)
}
//初始化相关数据的配置
InitData()
}
func runServer() {
port := bootstrap.Config.Iris.Port
controller.Router(port)
}
func InitData() {
initArticleData()
service.DiaryService.RefreshLatest()
initContentData()
initViewRecordData()
}
func initArticleData() {
var slices []model.BlogArticle = repository.ArticleRepository().FindList(nil, "state = ?", consts.ARTICLE_STATE_PUBLISH)
logrus.Info("文章初始化数据加载量:", len(slices))
ctx := context.Background()
for _, article := range slices {
// logrus.Info(article)
publishTime := article.PublishTime
err := client.RedisClient().ZAdd(ctx, consts.REDIS_BLOG_ARTICLE_LATEST, redis.Z{Score: float64(publishTime), Member: &article}).Err()
if err != nil {
logrus.Info(err)
}
}
}
func initContentData() {
var slices []model.BlogTextContent = repository.TextContentRepository().FindList(nil, "state = ?", consts.CONTENT_STATE_PUBLISH)
logrus.Info("大文本初始化数据加载量:", len(slices))
for _, content := range slices {
client.RedisClient().Set(context.Background(), consts.REDIS_BLOG_CONTENT+content.RelId, &content, time.Duration(0))
}
}
func initViewRecordData() {
type viewRecord struct {
RelId string
Counts int
}
var slices []viewRecord
repository.ViewRecordRep().Table(consts.TABLE_BLOG_VIEW_RECORD).Select("rel_id ,count(1) counts").Group("rel_id").Find(&slices)
logrus.Info("点击量初始化数据加载量:", len(slices))
for _, val := range slices {
client.RedisClient().HSet(context.Background(), consts.REDIS_BLOG_VIEW_RECORD, map[string]any{val.RelId: val.Counts})
}
}

View File

@ -11,6 +11,7 @@
<script src="/assets/vue/vue.min.js"></script>
<script src="/assets/vuetify-v2.6.9/vuetify-v2.6.9.min.js"></script>
<script src="/assets/axios/axios.min.js"></script>
<script src="/assets/moment/moment.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
@ -18,6 +19,20 @@
</body>
<script type="text/x-template" id="app-template">
<v-app id="inspire">
<v-dialog v-model="dialog.show" width="500" v-if="dialog.obj">
<v-card>
<v-card-title class="text-h5 grey lighten-2">{{dialog.title}}</v-card-title>
<v-card-text>{{dialog.context}}</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn text @click="dialog.show = false">取消</v-btn>
<v-spacer></v-spacer>
<v-btn color="primary" text @click="confirm">确认</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
#{render "common/bar-admin.html" .}
<v-main class="grey lighten-3">
<v-container style="height: 100%">
@ -68,6 +83,67 @@
</v-sheet>
</v-col>
<v-col cols="12" xs="12" sm="12" md="6">
<v-sheet min-height="100%">
<v-list three-line class="pt-0 pb-0">
<template v-for="(item, index) in diaryList">
<!-- <v-subheader v-if="item.header" :key="item.header" v-text="item.header"></v-subheader> -->
<v-list-item>
<!-- <v-list-item-avatar>
<v-img src="/assets/images/yage.jpg"></v-img>
</v-list-item-avatar> -->
<v-list-item-content style="display: block;">
<v-list-item-title>
<div>{{moment(item.publishTime).format('YYYY/MM/DD')}}</div>
<div style="white-space: break-spaces;">{{item.content}}</div>
</v-list-item-title>
<v-list-item-subtitle>
<v-row>
<template v-if="item.images.length===1">
<v-col v-for="id in item.images" :key="id" class="d-flex child-flex" cols="6">
<v-img :src="`/file/${id}`" aspect-ratio="1" class="grey lighten-2">
<template v-slot:placeholder>
<v-row class="fill-height ma-0" align="center" justify="center">
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
</v-row>
</template>
</v-img>
</v-col>
</template>
<template v-if="item.images.length>1">
<v-col v-for="id in item.images" :key="id" class="d-flex child-flex" cols="4">
<v-img :src="`/file/${id}`" aspect-ratio="1" class="grey lighten-2">
<template v-slot:placeholder>
<v-row class="fill-height ma-0" align="center" justify="center">
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
</v-row>
</template>
</v-img>
</v-col>
</template>
<!-- <v-col v-for="id in item.images" :key="id" class="d-flex child-flex" cols="4">
<v-img :src="`/file/${r'${id}'}`" aspect-ratio="1" class="grey lighten-2" @click="zoomImg(id)">
<template v-slot:placeholder>
<v-row class="fill-height ma-0" align="center" justify="center">
<v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
</v-row>
</template>
</v-img>
</v-col> -->
</v-row>
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-btn color="error" plain @click="delDiary(item)"><v-icon>mdi-delete</v-icon> 删除 </v-btn>
<v-divider></v-divider>
</template>
</v-list>
</v-sheet>
</v-col>
</v-row>
</v-container>
</v-main>
@ -87,7 +163,16 @@
content: '',
files: [],
images: [],
error: null
error: null,
dialog: {
show: false,
title: '',
context: '',
obj: null
},
diaryList: [],
},
methods: {
send() {
@ -103,7 +188,7 @@
let data = res.data
console.log(data)
this.sending = false
location.href = '/diary'
location.reload()
}).catch(err => {
ths.error = err
console.error(err)
@ -132,7 +217,60 @@
removeImg(index) {
this.images.splice(index, 1)
this.files.splice(index, 1)
}
},
delDiary(item){
let ths = this;
let id = item.id
this.dialog.obj = item
this.dialog.title = '删除文件'
this.dialog.context = `确认要删除该日记吗?`
this.dialog.show = true;
this.confirm = () => {
ths.dialog.show = false;
axios.delete(`/admin/diary/del/${id}`).then(res => {
let data = res.data
if (data.code === 200) {
ths.latestDiary()
return
}
}).catch(err => {
});
}
},
latestDiary() {
let ths = this
axios.get("/diary/latest").then(rsp => {
let data = rsp.data.data
return data
}).then((data) => {
data.forEach(item => {
let imgList = []
let images = item.images.split(",")
images.forEach(img => {
if(img){
imgList.push(img)
}
})
item.images = imgList
// console.log(imgList);
});
// console.log(data);
ths.diaryList = data
}).catch(err => {
})
},
},
mounted() {
this.latestDiary();
},
vuetify: new Vuetify(),

View File

@ -29,11 +29,11 @@
<v-main :class="$vuetify.theme.dark?'':'grey lighten-3'">
<v-container>
<v-row>
<v-col cols="12" xs="0" sm="0" md="2" class="d-sm-none d-md-flex d-none d-sm-flex">
<v-col cols="12" xs="12" sm="3" md="3" lg="3" xl="2" class="d-sm-none d-md-flex d-none d-sm-flex">
#{ render "blog/introduce.html" . }
</v-col>
<v-col cols="12" xs="12" sm="12" md="10">
<v-col cols="12" xs="12" sm="9" md="9">
<v-sheet min-height="100%" style="float: left;padding: 15px;" width="100%">
<h2>#{.article.Title}</h2>
#{ if ne .article.SubTitle ""}
@ -53,6 +53,13 @@
</v-app>
</script>
<style scope>
.v-sheet.theme--dark>#my-content {
background-color: #1e1e1e;
color: white;
}
</style>
<script>
new Vue({
el: '#app',

View File

@ -30,11 +30,11 @@
<v-main :class="$vuetify.theme.dark?'':'grey lighten-3'">
<v-container>
<v-row style="height: 100%">
<v-col cols="12" xs="0" sm="12" md="2" class="d-sm-none d-md-flex d-none d-sm-flex">
<v-col cols="12" xs="12" sm="3" md="3" lg="3" xl="2" class="d-sm-none d-md-flex d-none d-sm-flex">
#{ render "blog/introduce.html" . }
</v-col>
<v-col cols="12" xs="12" sm="12" md="10">
<v-col cols="12" xs="12" sm="9" md="9">
<v-sheet min-height="100%" style="float: left;padding: 15px;" width="100%">
<h2>#{.article.Title}</h2>
#{ if ne .article.SubTitle ""}
@ -42,7 +42,7 @@
#{end}
<v-subheader>发布时间: {{ publishTime?moment(parseInt(publishTime)).format('YYYY/MM/DD'):''}}</v-subheader>
<v-divider></v-divider>
#{.content}
<div class="article_content">#{.content}</div>
</v-sheet>
</v-col>

View File

@ -31,11 +31,11 @@
<v-main :class="$vuetify.theme.dark?'':'grey lighten-3'">
<v-container>
<v-row>
<v-col cols="12" xs="0" sm="12" md="2" offset-md="1">
<v-col cols="12" xs="12" sm="3" md="3" lg="3" xl="2" offset-xl="1">
#{ render "blog/introduce.html" . }
</v-col>
<v-col cols="12" xs="12" sm="12" md="6">
<v-col cols="12" xs="12" sm="6" md="6" lg="6" xl="6">
<v-sheet min-height="100%">
<v-list three-line class="pt-0 pb-0">
<template v-for="(item, index) in diaryList">
@ -94,7 +94,7 @@
</v-sheet>
</v-col>
<v-col cols="12" xs="12" sm="12" md="2">
<v-col cols="12" xs="12" sm="3" md="3" lg="3" xl="2">
<v-sheet min-height="100%">
</v-sheet>

View File

@ -7,7 +7,7 @@
<v-img height="250" src="/assets/images/logo.jpg">
<v-expand-transition>
<div v-if="hover" class="d-flex transition-fast-in-fast-out white darken-2 v-card--reveal"
style="align-items: center;justify-content: center;height: 100%">
style="align-items: center;justify-content: center;height: 100%; color: black;">
愿各位早日成为正式员工
</div>
</v-expand-transition>

View File

@ -23,11 +23,11 @@
<v-main :class="$vuetify.theme.dark?'':'grey lighten-3'">
<v-container>
<v-row>
<v-col cols="12" xs="12" sm="12" md="2" offset-md="1">
<v-col cols="12" xs="12" sm="3" md="3" lg="3" xl="2" offset-xl="1">
#{ render "blog/introduce.html" . }
</v-col>
<v-col cols="12" xs="12" sm="12" md="6">
<v-col cols="12" xs="12" sm="6" md="6" lg="6" xl="6">
<v-sheet min-height="100%">
<v-list three-line class="pt-0 pb-0">
<template v-for="(item, index) in articleList">
@ -66,7 +66,7 @@
</v-col>
<v-col cols="12" xs="12" sm="12" md="2">
<v-col cols="12" xs="12" sm="3" md="3" lg="3" xl="2">
<v-sheet min-height="100%" style="width: 100%">
<v-card>
<v-card-title class="text-h5">