mirror of https://github.com/mindoc-org/mindoc.git
parent
774530bbc2
commit
1cbdd4baca
|
@ -3,24 +3,56 @@ package cache
|
||||||
import (
|
import (
|
||||||
"github.com/astaxie/beego/cache"
|
"github.com/astaxie/beego/cache"
|
||||||
"time"
|
"time"
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"github.com/astaxie/beego"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bm cache.Cache
|
var bm cache.Cache
|
||||||
|
|
||||||
func Get(key string) interface{} {
|
func Get(key string,e interface{}) error {
|
||||||
|
|
||||||
return bm.Get(key)
|
val := bm.Get(key)
|
||||||
|
|
||||||
|
if val == nil {
|
||||||
|
return errors.New("cache does not exist")
|
||||||
|
}
|
||||||
|
if b,ok := val.([]byte); ok {
|
||||||
|
buf := bytes.NewBuffer(b)
|
||||||
|
|
||||||
|
decoder := gob.NewDecoder(buf)
|
||||||
|
|
||||||
|
err := decoder.Decode(e)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("反序列化对象失败 ->", err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return errors.New("value is not []byte")
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMulti(keys []string) []interface{} {
|
func GetMulti(keys []string) []interface{} {
|
||||||
|
|
||||||
return bm.GetMulti(keys)
|
return bm.GetMulti(keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Put(key string, val interface{}, timeout time.Duration) error {
|
func Put(key string, val interface{}, timeout time.Duration) error {
|
||||||
|
|
||||||
return bm.Put(key, val, timeout)
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
encoder := gob.NewEncoder(&buf)
|
||||||
|
|
||||||
|
err := encoder.Encode(val)
|
||||||
|
if err != nil {
|
||||||
|
beego.Error("序列化对象失败 ->",err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return bm.Put(key, buf.String(), timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Delete(key string) error {
|
func Delete(key string) error {
|
||||||
return bm.Delete(key)
|
return bm.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/lifei6671/mindoc/conf"
|
"github.com/lifei6671/mindoc/conf"
|
||||||
"github.com/lifei6671/mindoc/models"
|
"github.com/lifei6671/mindoc/models"
|
||||||
"github.com/lifei6671/mindoc/utils/filetil"
|
"github.com/lifei6671/mindoc/utils/filetil"
|
||||||
|
"github.com/astaxie/beego/cache/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterDataBase 注册数据库
|
// RegisterDataBase 注册数据库
|
||||||
|
@ -91,6 +92,8 @@ func RegisterModel() {
|
||||||
new(models.Label),
|
new(models.Label),
|
||||||
new(models.Blog),
|
new(models.Blog),
|
||||||
)
|
)
|
||||||
|
gob.Register(models.Blog{})
|
||||||
|
gob.Register(models.Document{})
|
||||||
//migrate.RegisterMigration()
|
//migrate.RegisterMigration()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,28 +103,69 @@ func RegisterLogger(log string) {
|
||||||
logs.SetLogFuncCall(true)
|
logs.SetLogFuncCall(true)
|
||||||
logs.SetLogger("console")
|
logs.SetLogger("console")
|
||||||
logs.EnableFuncCallDepth(true)
|
logs.EnableFuncCallDepth(true)
|
||||||
logs.Async()
|
|
||||||
|
if beego.AppConfig.DefaultBool("log_is_async", true) {
|
||||||
|
logs.Async(1e3)
|
||||||
|
}
|
||||||
|
if log == "" {
|
||||||
|
log = conf.WorkingDir("runtime","logs")
|
||||||
|
}
|
||||||
|
|
||||||
logPath := filepath.Join(log, "log.log")
|
logPath := filepath.Join(log, "log.log")
|
||||||
|
|
||||||
if _, err := os.Stat(logPath); os.IsNotExist(err) {
|
if _, err := os.Stat(log); os.IsNotExist(err) {
|
||||||
|
|
||||||
os.MkdirAll(log, 0777)
|
os.MkdirAll(log, 0777)
|
||||||
|
}
|
||||||
|
|
||||||
if f, err := os.Create(logPath); err == nil {
|
|
||||||
f.Close()
|
|
||||||
config := make(map[string]interface{}, 1)
|
config := make(map[string]interface{}, 1)
|
||||||
|
|
||||||
config["filename"] = logPath
|
config["filename"] = logPath
|
||||||
|
config["perm"] = "0755"
|
||||||
|
config["rotate"] = true
|
||||||
|
|
||||||
b, _ := json.Marshal(config)
|
if maxLines := beego.AppConfig.DefaultInt("log_maxlines", 1000000); maxLines > 0 {
|
||||||
|
config["maxLines"] = maxLines
|
||||||
beego.SetLogger("file", string(b))
|
}
|
||||||
|
if maxSize := beego.AppConfig.DefaultInt("log_maxsize", 1<<28); maxSize > 0 {
|
||||||
|
config["maxsize"] = maxSize
|
||||||
|
}
|
||||||
|
if !beego.AppConfig.DefaultBool("log_daily", true) {
|
||||||
|
config["daily"] = false
|
||||||
|
}
|
||||||
|
if maxDays := beego.AppConfig.DefaultInt("log_maxdays", 7); maxDays > 0 {
|
||||||
|
config["maxdays"] = maxDays
|
||||||
|
}
|
||||||
|
if level := beego.AppConfig.DefaultString("log_level", "Trace"); level != "" {
|
||||||
|
switch level {
|
||||||
|
case "Emergency":
|
||||||
|
config["level"] = beego.LevelEmergency;break
|
||||||
|
case "Alert":
|
||||||
|
config["level"] = beego.LevelAlert;break
|
||||||
|
case "Critical":
|
||||||
|
config["level"] = beego.LevelCritical;break
|
||||||
|
case "Error":
|
||||||
|
config["level"] = beego.LevelError; break
|
||||||
|
case "Warning":
|
||||||
|
config["level"] = beego.LevelWarning; break
|
||||||
|
case "Notice":
|
||||||
|
config["level"] = beego.LevelNotice; break
|
||||||
|
case "Informational":
|
||||||
|
config["level"] = beego.LevelInformational;break
|
||||||
|
case "Debug":
|
||||||
|
config["level"] = beego.LevelDebug;break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b, err := json.Marshal(config);
|
||||||
|
if err != nil {
|
||||||
|
beego.Error("初始化文件日志时出错 ->",err)
|
||||||
|
beego.SetLogger("file", `{"filename":"`+ logPath + `"}`)
|
||||||
|
}else{
|
||||||
|
beego.SetLogger(logs.AdapterFile, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
beego.SetLogFuncCall(true)
|
beego.SetLogFuncCall(true)
|
||||||
beego.BeeLogger.Async()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunCommand 注册orm命令行工具
|
// RunCommand 注册orm命令行工具
|
||||||
|
@ -270,6 +314,10 @@ func RegisterCache() {
|
||||||
beegoCache.DefaultEvery = cacheInterval
|
beegoCache.DefaultEvery = cacheInterval
|
||||||
cache.Init(memory)
|
cache.Init(memory)
|
||||||
} else if cacheProvider == "redis" {
|
} else if cacheProvider == "redis" {
|
||||||
|
//设置Redis前缀
|
||||||
|
if key := beego.AppConfig.DefaultString("cache_redis_prefix",""); key != "" {
|
||||||
|
redis.DefaultKey = key
|
||||||
|
}
|
||||||
var redisConfig struct {
|
var redisConfig struct {
|
||||||
Conn string `json:"conn"`
|
Conn string `json:"conn"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
|
@ -320,7 +368,7 @@ func RegisterCache() {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cache.Init(&cache.NullCache{})
|
cache.Init(&cache.NullCache{})
|
||||||
beego.Warn("不支持的缓存管道,缓存将禁用.")
|
beego.Warn("不支持的缓存管道,缓存将禁用 ->" ,cacheProvider)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
beego.Info("缓存初始化完成.")
|
beego.Info("缓存初始化完成.")
|
||||||
|
|
|
@ -26,6 +26,8 @@ sessionproviderconfig=./runtime/session
|
||||||
#时区设置
|
#时区设置
|
||||||
timezone = Asia/Shanghai
|
timezone = Asia/Shanghai
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
####################MySQL 数据库配置###########################
|
####################MySQL 数据库配置###########################
|
||||||
#支持MySQL和sqlite3两种数据库,如果是sqlite3 则 db_database 标识数据库的物理目录
|
#支持MySQL和sqlite3两种数据库,如果是sqlite3 则 db_database 标识数据库的物理目录
|
||||||
db_adapter=mysql
|
db_adapter=mysql
|
||||||
|
@ -87,12 +89,6 @@ export_queue_limit_num=100
|
||||||
#导出项目的缓存目录配置
|
#导出项目的缓存目录配置
|
||||||
export_output_path=./runtime/cache
|
export_output_path=./runtime/cache
|
||||||
|
|
||||||
###############配置CDN加速##################
|
|
||||||
cdn=
|
|
||||||
cdnjs=
|
|
||||||
cdncss=
|
|
||||||
cdnimg=
|
|
||||||
|
|
||||||
################百度地图密钥#################
|
################百度地图密钥#################
|
||||||
baidumapkey=
|
baidumapkey=
|
||||||
|
|
||||||
|
@ -116,35 +112,73 @@ ldap_user_role=2
|
||||||
#ldap搜索filter规则,AD服务器: objectClass=User, openldap服务器: objectClass=posixAccount ,也可以定义为其他属性,如: title=mindoc
|
#ldap搜索filter规则,AD服务器: objectClass=User, openldap服务器: objectClass=posixAccount ,也可以定义为其他属性,如: title=mindoc
|
||||||
ldap_filter=objectClass=posixAccount
|
ldap_filter=objectClass=posixAccount
|
||||||
|
|
||||||
|
###############配置CDN加速##################
|
||||||
|
cdn=
|
||||||
|
cdnjs=
|
||||||
|
cdncss=
|
||||||
|
cdnimg=
|
||||||
|
|
||||||
######################缓存配置###############################
|
######################缓存配置###############################
|
||||||
|
|
||||||
#是否开启缓存,true 开启/false 不开启
|
#是否开启缓存,true 开启/false 不开启
|
||||||
cache=false
|
cache=false
|
||||||
|
|
||||||
#缓存方式:memory/memcache/redis/file
|
#缓存方式:memory/memcache/redis/file
|
||||||
cache_provider=memory
|
cache_provider=memory
|
||||||
|
|
||||||
#当配置缓存方式为memory时,内存回收时间,单位是秒
|
#当配置缓存方式为memory时,内存回收时间,单位是秒
|
||||||
cache_memory_interval=120
|
cache_memory_interval=120
|
||||||
|
|
||||||
#当缓存方式配置为file时,缓存的储存目录
|
#当缓存方式配置为file时,缓存的储存目录
|
||||||
cache_file_path=./runtime/cache/
|
cache_file_path=./runtime/cache/
|
||||||
|
|
||||||
#缓存文件后缀
|
#缓存文件后缀
|
||||||
cache_file_suffix=.bin
|
cache_file_suffix=.bin
|
||||||
|
|
||||||
#文件缓存目录层级
|
#文件缓存目录层级
|
||||||
cache_file_dir_level=2
|
cache_file_dir_level=2
|
||||||
|
|
||||||
#文件缓存的默认过期时间
|
#文件缓存的默认过期时间
|
||||||
cache_file_expiry=3600
|
cache_file_expiry=3600
|
||||||
|
|
||||||
#memcache缓存服务器地址
|
#memcache缓存服务器地址
|
||||||
cache_memcache_host=127.0.0.1:11211
|
cache_memcache_host=127.0.0.1:11211
|
||||||
|
|
||||||
#redis服务器地址
|
#redis服务器地址
|
||||||
cache_redis_host=127.0.0.1:6379
|
cache_redis_host=127.0.0.1:6379
|
||||||
|
|
||||||
#redis数据库索引
|
#redis数据库索引
|
||||||
cache_redis_db=0
|
cache_redis_db=0
|
||||||
|
|
||||||
#redis服务器密码
|
#redis服务器密码
|
||||||
cache_redis_password=
|
cache_redis_password=
|
||||||
|
|
||||||
|
#缓存键的前缀
|
||||||
|
cache_redis_prefix=mindoc::cache
|
||||||
|
|
||||||
|
|
||||||
|
#########日志储存配置##############
|
||||||
|
|
||||||
|
#日志保存路径,在linux上,自动创建的日志文件请不要删除,否则将无法写入日志
|
||||||
|
log_path=./runtime/logs
|
||||||
|
|
||||||
|
#每个文件保存的最大行数,默认值 1000000
|
||||||
|
log_maxlines=1000000
|
||||||
|
|
||||||
|
# 每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB
|
||||||
|
log_maxsize=
|
||||||
|
|
||||||
|
# 是否按照每天 logrotate,默认是 true
|
||||||
|
log_daily=true
|
||||||
|
|
||||||
|
# 文件最多保存多少天,默认保存 7 天
|
||||||
|
log_maxdays=30
|
||||||
|
|
||||||
|
# 日志保存的时候的级别,默认是 Trace 级别,可选值: Emergency/Alert/Critical/Error/Warning/Notice/Informational/Debug/Trace
|
||||||
|
log_level=Trace
|
||||||
|
|
||||||
|
# 是否异步生成日志,默认是 true
|
||||||
|
log_is_async=true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
"html/template"
|
"html/template"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/lifei6671/mindoc/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlogController struct{
|
type BlogController struct{
|
||||||
|
@ -58,6 +59,13 @@ func (c *BlogController) Index() {
|
||||||
c.Data["Model"] = blog
|
c.Data["Model"] = blog
|
||||||
c.Data["Content"] = template.HTML(blog.BlogRelease)
|
c.Data["Content"] = template.HTML(blog.BlogRelease)
|
||||||
|
|
||||||
|
if blog.BlogExcerpt == "" {
|
||||||
|
c.Data["Description"] = utils.AutoSummary(blog.BlogRelease,120)
|
||||||
|
}else{
|
||||||
|
c.Data["Description"] = blog.BlogExcerpt
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if nextBlog,err := models.NewBlog().QueryNext(blogId);err == nil {
|
if nextBlog,err := models.NewBlog().QueryNext(blogId);err == nil {
|
||||||
c.Data["Next"] = nextBlog
|
c.Data["Next"] = nextBlog
|
||||||
}
|
}
|
||||||
|
@ -86,6 +94,10 @@ func (c *BlogController) List() {
|
||||||
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
|
pager := pagination.NewPagination(c.Ctx.Request, totalCount, conf.PageSize, c.BaseUrl())
|
||||||
c.Data["PageHtml"] = pager.HtmlPages()
|
c.Data["PageHtml"] = pager.HtmlPages()
|
||||||
for _,blog := range blogList {
|
for _,blog := range blogList {
|
||||||
|
//如果没有添加文章摘要,则自动提取
|
||||||
|
if blog.BlogExcerpt == "" {
|
||||||
|
blog.BlogExcerpt = utils.AutoSummary(blog.BlogRelease,120)
|
||||||
|
}
|
||||||
blog.Link()
|
blog.Link()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -70,6 +70,7 @@ func (c *DocumentController) Index() {
|
||||||
c.Data["Title"] = doc.DocumentName
|
c.Data["Title"] = doc.DocumentName
|
||||||
c.Data["Content"] = template.HTML(doc.Release)
|
c.Data["Content"] = template.HTML(doc.Release)
|
||||||
|
|
||||||
|
c.Data["Description"] = utils.AutoSummary(doc.Release,120)
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
c.Data["Title"] = "概要"
|
c.Data["Title"] = "概要"
|
||||||
|
@ -208,6 +209,10 @@ func (c *DocumentController) Read() {
|
||||||
c.Abort("500")
|
c.Abort("500")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
c.Data["Description"] = utils.AutoSummary(doc.Release,120)
|
||||||
|
|
||||||
|
|
||||||
c.Data["Model"] = bookResult
|
c.Data["Model"] = bookResult
|
||||||
c.Data["Result"] = template.HTML(tree)
|
c.Data["Result"] = template.HTML(tree)
|
||||||
c.Data["Title"] = doc.DocumentName
|
c.Data["Title"] = doc.DocumentName
|
||||||
|
|
|
@ -510,8 +510,6 @@ func (this *Converter) convertToMobi() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
filepath.Join(this.OutputPath, "content.epub"),
|
filepath.Join(this.OutputPath, "content.epub"),
|
||||||
filepath.Join(this.OutputPath, output, "book.mobi"),
|
filepath.Join(this.OutputPath, output, "book.mobi"),
|
||||||
"--debug-pipeline",
|
|
||||||
"--verbose",
|
|
||||||
}
|
}
|
||||||
cmd := exec.Command(ebookConvert, args...)
|
cmd := exec.Command(ebookConvert, args...)
|
||||||
if this.Debug {
|
if this.Debug {
|
||||||
|
@ -526,8 +524,6 @@ func (this *Converter) convertToPdf() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
filepath.Join(this.OutputPath, "content.epub"),
|
filepath.Join(this.OutputPath, "content.epub"),
|
||||||
filepath.Join(this.OutputPath, output, "book.pdf"),
|
filepath.Join(this.OutputPath, output, "book.pdf"),
|
||||||
"--debug-pipeline",
|
|
||||||
"--verbose",
|
|
||||||
}
|
}
|
||||||
//页面大小
|
//页面大小
|
||||||
if len(this.Config.PaperSize) > 0 {
|
if len(this.Config.PaperSize) > 0 {
|
||||||
|
@ -579,8 +575,6 @@ func (this *Converter) convertToDocx() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
filepath.Join(this.OutputPath , "content.epub"),
|
filepath.Join(this.OutputPath , "content.epub"),
|
||||||
filepath.Join(this.OutputPath , output , "book.docx"),
|
filepath.Join(this.OutputPath , output , "book.docx"),
|
||||||
"--debug-pipeline",
|
|
||||||
"--verbose",
|
|
||||||
}
|
}
|
||||||
args = append(args, "--docx-no-toc")
|
args = append(args, "--docx-no-toc")
|
||||||
|
|
||||||
|
|
|
@ -103,18 +103,18 @@ func (b *Blog) Find(blogId int) (*Blog,error) {
|
||||||
//从缓存中读取文章
|
//从缓存中读取文章
|
||||||
func (b *Blog) FindFromCache(blogId int) (blog *Blog,err error) {
|
func (b *Blog) FindFromCache(blogId int) (blog *Blog,err error) {
|
||||||
key := fmt.Sprintf("blog-id-%d",blogId);
|
key := fmt.Sprintf("blog-id-%d",blogId);
|
||||||
obj := cache.Get(key)
|
var temp Blog
|
||||||
|
if err := cache.Get(key,&temp); err == nil {
|
||||||
if b,ok := obj.(Blog); ok {
|
b = &temp
|
||||||
blog = &b
|
b.Link()
|
||||||
blog.Link()
|
|
||||||
beego.Info("从缓存读取文章成功 ->", key)
|
beego.Info("从缓存读取文章成功 ->", key)
|
||||||
return
|
return b,nil
|
||||||
}
|
}
|
||||||
|
|
||||||
blog,err = b.Find(blogId)
|
blog,err = b.Find(blogId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
//默认一个小时
|
//默认一个小时
|
||||||
if err := cache.Put(key,*blog,time.Hour * 1); err != nil {
|
if err := cache.Put(key,blog,time.Hour * 1); err != nil {
|
||||||
beego.Error("将文章存入缓存失败 ->",err)
|
beego.Error("将文章存入缓存失败 ->",err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ func (b *Blog) Save(cols ...string) error {
|
||||||
if b.BlogId > 0 {
|
if b.BlogId > 0 {
|
||||||
b.Modified = time.Now()
|
b.Modified = time.Now()
|
||||||
_,err = o.Update(b,cols...)
|
_,err = o.Update(b,cols...)
|
||||||
key := fmt.Sprintf("blog-id-%d",b.BlogId);
|
key := fmt.Sprintf("blog-id-%d", b.BlogId )
|
||||||
cache.Delete(key)
|
cache.Delete(key)
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
@ -320,7 +320,7 @@ func (b *Blog) QueryNext(blogId int) (*Blog,error) {
|
||||||
|
|
||||||
err := o.QueryTable(b.TableNameWithPrefix()).Filter("order_index__gte",blog.OrderIndex).Filter("blog_id__gt",blogId).OrderBy("-order_index","-blog_id").One(blog)
|
err := o.QueryTable(b.TableNameWithPrefix()).Filter("order_index__gte",blog.OrderIndex).Filter("blog_id__gt",blogId).OrderBy("-order_index","-blog_id").One(blog)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil && err != orm.ErrNoRows{
|
||||||
beego.Error("查询文章时出错 ->",err)
|
beego.Error("查询文章时出错 ->",err)
|
||||||
}
|
}
|
||||||
return blog,err
|
return blog,err
|
||||||
|
@ -338,7 +338,7 @@ func (b *Blog) QueryPrevious(blogId int) (*Blog,error) {
|
||||||
|
|
||||||
err := o.QueryTable(b.TableNameWithPrefix()).Filter("order_index__lte",blog.OrderIndex).Filter("blog_id__lt",blogId).OrderBy("-order_index","-blog_id").One(blog)
|
err := o.QueryTable(b.TableNameWithPrefix()).Filter("order_index__lte",blog.OrderIndex).Filter("blog_id__lt",blogId).OrderBy("-order_index","-blog_id").One(blog)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil && err != orm.ErrNoRows{
|
||||||
beego.Error("查询文章时出错 ->",err)
|
beego.Error("查询文章时出错 ->",err)
|
||||||
}
|
}
|
||||||
return blog,err
|
return blog,err
|
||||||
|
@ -353,13 +353,13 @@ func (b *Blog) LinkAttach() (err error) {
|
||||||
//当不是关联文章时,用文章ID去查询附件
|
//当不是关联文章时,用文章ID去查询附件
|
||||||
if b.BlogType != 1 || b.DocumentId <= 0 {
|
if b.BlogType != 1 || b.DocumentId <= 0 {
|
||||||
_, err = o.QueryTable(NewAttachment().TableNameWithPrefix()).Filter("document_id", b.BlogId).Filter("book_id",0).All(&attachList)
|
_, err = o.QueryTable(NewAttachment().TableNameWithPrefix()).Filter("document_id", b.BlogId).Filter("book_id",0).All(&attachList)
|
||||||
if err != nil {
|
if err != nil && err != orm.ErrNoRows{
|
||||||
beego.Error("查询文章附件时出错 ->", err)
|
beego.Error("查询文章附件时出错 ->", err)
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
_, err = o.QueryTable(NewAttachment().TableNameWithPrefix()).Filter("document_id", b.DocumentId).Filter("book_id", b.BookId).All(&attachList)
|
_, err = o.QueryTable(NewAttachment().TableNameWithPrefix()).Filter("document_id", b.DocumentId).Filter("book_id", b.BookId).All(&attachList)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil && err != orm.ErrNoRows{
|
||||||
beego.Error("查询文章附件时出错 ->", err)
|
beego.Error("查询文章附件时出错 ->", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package models
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
@ -151,18 +150,18 @@ func (m *Document) RecursiveDocument(docId int) error {
|
||||||
//将文档写入缓存
|
//将文档写入缓存
|
||||||
func (m *Document) PutToCache() {
|
func (m *Document) PutToCache() {
|
||||||
go func(m Document) {
|
go func(m Document) {
|
||||||
if v, err := json.Marshal(&m); err == nil {
|
|
||||||
if m.Identify == "" {
|
if m.Identify == "" {
|
||||||
|
|
||||||
if err := cache.Put("Document.Id."+strconv.Itoa(m.DocumentId), v, time.Second*3600); err != nil {
|
if err := cache.Put("Document.Id."+strconv.Itoa(m.DocumentId), m, time.Second*3600); err != nil {
|
||||||
beego.Info("文档缓存失败:", m.DocumentId)
|
beego.Info("文档缓存失败:", m.DocumentId)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := cache.Put(fmt.Sprintf("Document.BookId.%d.Identify.%s", m.BookId, m.Identify), v, time.Second*3600); err != nil {
|
if err := cache.Put(fmt.Sprintf("Document.BookId.%d.Identify.%s", m.BookId, m.Identify), m, time.Second*3600); err != nil {
|
||||||
beego.Info("文档缓存失败:", m.DocumentId)
|
beego.Info("文档缓存失败:", m.DocumentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}(*m)
|
}(*m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,31 +178,35 @@ func (m *Document) RemoveCache() {
|
||||||
|
|
||||||
//从缓存获取
|
//从缓存获取
|
||||||
func (m *Document) FromCacheById(id int) (*Document, error) {
|
func (m *Document) FromCacheById(id int) (*Document, error) {
|
||||||
b := cache.Get("Document.Id." + strconv.Itoa(id))
|
|
||||||
if v, ok := b.([]byte); ok {
|
|
||||||
|
|
||||||
if err := json.Unmarshal(v, m); err == nil {
|
var doc Document
|
||||||
|
if err := cache.Get("Document.Id."+strconv.Itoa(id), &m); err == nil {
|
||||||
|
m = &doc
|
||||||
beego.Info("从缓存中获取文档信息成功", m.DocumentId)
|
beego.Info("从缓存中获取文档信息成功", m.DocumentId)
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if m.DocumentId > 0 {
|
if m.DocumentId > 0 {
|
||||||
m.PutToCache()
|
m.PutToCache()
|
||||||
}
|
}
|
||||||
}()
|
m,err := m.Find(id)
|
||||||
return m.Find(id)
|
|
||||||
|
if err == nil {
|
||||||
|
m.PutToCache()
|
||||||
|
}
|
||||||
|
return m,err
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据文档标识从缓存中查询文档
|
//根据文档标识从缓存中查询文档
|
||||||
func (m *Document) FromCacheByIdentify(identify string, bookId int) (*Document, error) {
|
func (m *Document) FromCacheByIdentify(identify string, bookId int) (*Document, error) {
|
||||||
b := cache.Get(fmt.Sprintf("Document.BookId.%d.Identify.%s", bookId, identify))
|
|
||||||
if v, ok := b.([]byte); ok {
|
key := fmt.Sprintf("Document.BookId.%d.Identify.%s", bookId, identify)
|
||||||
if err := json.Unmarshal(v, m); err == nil {
|
|
||||||
beego.Info("从缓存中获取文档信息成功", m.DocumentId, identify)
|
if err := cache.Get(key,m); err == nil {
|
||||||
|
beego.Info("从缓存中获取文档信息成功", key)
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if m.DocumentId > 0 {
|
if m.DocumentId > 0 {
|
||||||
m.PutToCache()
|
m.PutToCache()
|
||||||
|
|
|
@ -29,3 +29,28 @@ func StripTags(s string) string {
|
||||||
|
|
||||||
return src
|
return src
|
||||||
}
|
}
|
||||||
|
//自动提取文章摘要
|
||||||
|
func AutoSummary(body string,l int) string {
|
||||||
|
|
||||||
|
//匹配图片,如果图片语法是在代码块中,这里同样会处理
|
||||||
|
re := regexp.MustCompile(`<p>(.*?)</p>`)
|
||||||
|
|
||||||
|
contents := re.FindAllString(body, -1)
|
||||||
|
|
||||||
|
if len(contents) <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
content := ""
|
||||||
|
for _,s := range contents {
|
||||||
|
b := strings.Replace(StripTags(s),"\n","", -1)
|
||||||
|
|
||||||
|
if l <= 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
l = l - len([]rune(b))
|
||||||
|
|
||||||
|
content += b
|
||||||
|
|
||||||
|
}
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<meta name="author" content="Minho" />
|
<meta name="author" content="Minho" />
|
||||||
<meta name="site" content="https://www.iminho.me" />
|
<meta name="site" content="https://www.iminho.me" />
|
||||||
<meta name="keywords" content="{{.Model.BlogTitle}}">
|
<meta name="keywords" content="{{.Model.BlogTitle}}">
|
||||||
<meta name="description" content="{{.Model.BlogTitle}}-{{.Model.BlogExcerpt}}">
|
<meta name="description" content="{{.Model.BlogTitle}}-{{.Description}}">
|
||||||
<title>{{.Model.BlogTitle}} - Powered by MinDoc</title>
|
<title>{{.Model.BlogTitle}} - Powered by MinDoc</title>
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
<!-- Bootstrap -->
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<meta name="author" content="Minho" />
|
<meta name="author" content="Minho" />
|
||||||
<meta name="site" content="https://www.iminho.me" />
|
<meta name="site" content="https://www.iminho.me" />
|
||||||
<meta name="keywords" content="{{.Model.BookName}},{{.Title}}">
|
<meta name="keywords" content="{{.Model.BookName}},{{.Title}}">
|
||||||
<meta name="description" content="{{.Title}}-{{.Model.Description}}">
|
<meta name="description" content="{{.Title}}-{{if .Description}}{{.Description}}{{else}}{{.Model.Description}}{{end}}">
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
<!-- Bootstrap -->
|
||||||
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/bootstrap/css/bootstrap.min.css"}}" rel="stylesheet">
|
||||||
|
|
Loading…
Reference in New Issue