Compare commits

...

7 Commits

Author SHA1 Message Date
henry.chen
eca741896f chore(release): 2.1.17 2023-01-05 13:28:48 +08:00
henry.chen
17792e5a7e fix: fist comment of disqus error 2023-01-05 13:25:18 +08:00
henry.chen
04289c633e chore: optimize variable naming 2023-01-05 11:07:56 +08:00
henry.chen
3a5eb6fccc chore(release): 2.1.18 2023-01-05 09:17:39 +08:00
henry.chen
f6d8656c83 fix: 1. template read panic
2. optimization variable naming
2023-01-05 09:17:31 +08:00
henry.chen
4690d5123b chore(release): 2.1.17 2023-01-05 00:00:11 +08:00
henry.chen
a9e8e39d34 fix(disqus): failed to commit disqus comments 2023-01-04 23:58:50 +08:00
12 changed files with 139 additions and 60 deletions

1
.gitignore vendored
View File

@@ -19,3 +19,4 @@ backend
# vendor/ # vendor/
bin bin
assets/*.* assets/*.*
db.sqlite

View File

@@ -2,6 +2,15 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [2.1.17](https://github.com/eiblog/eiblog/compare/v2.1.16...v2.1.17) (2023-01-05)
### Bug Fixes
* 1. template read panic ([f6d8656](https://github.com/eiblog/eiblog/commit/f6d8656c83591584581383643d109611d7ed2caa))
* **disqus:** failed to commit disqus comments ([a9e8e39](https://github.com/eiblog/eiblog/commit/a9e8e39d342488ec46175997f3df9ab109f2fecf))
* fist comment of disqus error ([17792e5](https://github.com/eiblog/eiblog/commit/17792e5a7edb7e84623d9307555e7983ba306565))
### [2.1.16](https://github.com/eiblog/eiblog/compare/v2.1.15...v2.1.16) (2022-11-20) ### [2.1.16](https://github.com/eiblog/eiblog/compare/v2.1.15...v2.1.16) (2022-11-20)

12
pkg/cache/cache.go vendored
View File

@@ -25,9 +25,11 @@ var (
// Ei eiblog cache // Ei eiblog cache
Ei *Cache Ei *Cache
// regenerate pages chan // PagesCh regenerate pages chan
PagesCh = make(chan string, 2) PagesCh = make(chan string, 2)
PageSeries = "series-md" // PageSeries the page series regenerate flag
PageSeries = "series-md"
// PageArchive the page archive regenerate flag
PageArchive = "archive-md" PageArchive = "archive-md"
// ArticleStartID article start id // ArticleStartID article start id
@@ -518,7 +520,7 @@ func (c *Cache) regeneratePages() {
} }
buf.WriteString("\n") buf.WriteString("\n")
} }
c.PageSeries = string(render.RenderPage(buf.Bytes())) c.PageSeries = string(render.PageRender(buf.Bytes()))
case PageArchive: case PageArchive:
sort.Sort(c.Archives) sort.Sort(c.Archives)
buf := bytes.Buffer{} buf := bytes.Buffer{}
@@ -551,7 +553,7 @@ func (c *Cache) regeneratePages() {
} }
} }
} }
c.PageArchives = string(render.RenderPage(buf.Bytes())) c.PageArchives = string(render.PageRender(buf.Bytes()))
} }
} }
} }

View File

@@ -14,7 +14,7 @@ import (
// blackfriday 配置 // blackfriday 配置
const ( const (
commonHtmlFlags = 0 | commonHTMLFlags = 0 |
blackfriday.HTML_TOC | blackfriday.HTML_TOC |
blackfriday.HTML_USE_XHTML | blackfriday.HTML_USE_XHTML |
blackfriday.HTML_USE_SMARTYPANTS | blackfriday.HTML_USE_SMARTYPANTS |
@@ -42,9 +42,9 @@ var (
regHeader = regexp.MustCompile("</nav></div>") regHeader = regexp.MustCompile("</nav></div>")
) )
// RenderPage 渲染markdown // PageRender 渲染markdown
func RenderPage(md []byte) []byte { func PageRender(md []byte) []byte {
renderer := blackfriday.HtmlRenderer(commonHtmlFlags, "", "") renderer := blackfriday.HtmlRenderer(commonHTMLFlags, "", "")
return blackfriday.Markdown(md, renderer, commonExtensions) return blackfriday.Markdown(md, renderer, commonExtensions)
} }
@@ -56,12 +56,12 @@ func GenerateExcerptMarkdown(article *model.Article) {
index := strings.Index(article.Content, "\r\n") index := strings.Index(article.Content, "\r\n")
prefix := article.Content[len(blogapp.General.DescPrefix):index] prefix := article.Content[len(blogapp.General.DescPrefix):index]
article.Desc = tools.IgnoreHtmlTag(prefix) article.Desc = tools.IgnoreHTMLTag(prefix)
article.Content = article.Content[index:] article.Content = article.Content[index:]
} }
// 查找目录 // 查找目录
content := RenderPage([]byte(article.Content)) content := PageRender([]byte(article.Content))
index := regHeader.FindIndex(content) index := regHeader.FindIndex(content)
if index != nil { if index != nil {
article.Header = string(content[0:index[1]]) article.Header = string(content[0:index[1]])
@@ -73,7 +73,7 @@ func GenerateExcerptMarkdown(article *model.Article) {
// excerpt // excerpt
index = regIdentifier.FindStringIndex(article.Content) index = regIdentifier.FindStringIndex(article.Content)
if index != nil { if index != nil {
article.Excerpt = tools.IgnoreHtmlTag(article.Content[:index[0]]) article.Excerpt = tools.IgnoreHTMLTag(article.Content[:index[0]])
return return
} }
uc := []rune(article.Content) uc := []rune(article.Content)
@@ -81,5 +81,5 @@ func GenerateExcerptMarkdown(article *model.Article) {
if len(uc) < length { if len(uc) < length {
length = len(uc) length = len(uc)
} }
article.Excerpt = tools.IgnoreHtmlTag(string(uc[0:length])) article.Excerpt = tools.IgnoreHTMLTag(string(uc[0:length]))
} }

View File

@@ -301,7 +301,7 @@ func handleAPIPostCreate(c *gin.Context) {
} }
// 旧文章 // 旧文章
article.ID = cid article.ID = cid
artc, _ := cache.Ei.FindArticleByID(article.ID) artc, _ := cache.Ei.FindArticleByID(article.ID) // cache
if artc != nil { if artc != nil {
article.IsDraft = false article.IsDraft = false
article.Count = artc.Count article.Count = artc.Count

View File

@@ -50,6 +50,7 @@ func handleAdminProfile(c *gin.Context) {
renderHTMLAdminLayout(c, "admin-profile", params) renderHTMLAdminLayout(c, "admin-profile", params)
} }
// T tag struct
type T struct { type T struct {
ID string `json:"id"` ID string `json:"id"`
Tags string `json:"tags"` Tags string `json:"tags"`

View File

@@ -3,6 +3,7 @@ package page
import ( import (
"bytes" "bytes"
"context"
"fmt" "fmt"
htemplate "html/template" htemplate "html/template"
"io/ioutil" "io/ioutil"
@@ -198,7 +199,8 @@ func handleDisqusList(c *gin.Context) {
slug := c.Param("slug") slug := c.Param("slug")
cursor := c.Query("cursor") cursor := c.Query("cursor")
if artc := cache.Ei.ArticlesMap[slug]; artc != nil { artc := cache.Ei.ArticlesMap[slug]
if artc != nil {
dcs.Data.Thread = artc.Thread dcs.Data.Thread = artc.Thread
} }
postsList, err := internal.PostsList(slug, cursor) postsList, err := internal.PostsList(slug, cursor)
@@ -222,13 +224,25 @@ func handleDisqusList(c *gin.Context) {
ID: v.ID, ID: v.ID,
Name: v.Author.Name, Name: v.Author.Name,
Parent: v.Parent, Parent: v.Parent,
Url: v.Author.ProfileUrl, URL: v.Author.ProfileURL,
Avatar: v.Author.Avatar.Cache, Avatar: v.Author.Avatar.Cache,
CreatedAtStr: tools.ConvertStr(v.CreatedAt), CreatedAtStr: tools.ConvertStr(v.CreatedAt),
Message: v.Message, Message: v.Message,
IsDeleted: v.IsDeleted, IsDeleted: v.IsDeleted,
} }
} }
// query thread & update
if artc != nil && artc.Thread == "" {
if dcs.Data.Thread != "" {
artc.Thread = dcs.Data.Thread
} else if internal.ThreadDetails(artc) == nil {
dcs.Data.Thread = artc.Thread
}
cache.Ei.UpdateArticle(context.Background(), artc.ID,
map[string]interface{}{
"thread": artc.Thread,
})
}
} }
// handleDisqusPage 评论页 // handleDisqusPage 评论页
@@ -261,7 +275,7 @@ type commentsDetail struct {
ID string `json:"id"` ID string `json:"id"`
Parent int `json:"parent"` Parent int `json:"parent"`
Name string `json:"name"` Name string `json:"name"`
Url string `json:"url"` URL string `json:"url"`
Avatar string `json:"avatar"` Avatar string `json:"avatar"`
CreatedAtStr string `json:"createdAtStr"` CreatedAtStr string `json:"createdAtStr"`
Message string `json:"message"` Message string `json:"message"`
@@ -274,7 +288,7 @@ func handleDisqusCreate(c *gin.Context) {
defer c.JSON(http.StatusOK, resp) defer c.JSON(http.StatusOK, resp)
msg := c.PostForm("message") msg := c.PostForm("message")
email := c.PostForm("author_name") email := c.PostForm("author_email")
name := c.PostForm("author_name") name := c.PostForm("author_name")
thread := c.PostForm("thread") thread := c.PostForm("thread")
identifier := c.PostForm("identifier") identifier := c.PostForm("identifier")
@@ -283,7 +297,7 @@ func handleDisqusCreate(c *gin.Context) {
resp.ErrMsg = "参数错误" resp.ErrMsg = "参数错误"
return return
} }
logrus.Info("email: %s comments: %s", email, thread) logrus.Infof("email: %s comments: %s", email, thread)
comment := internal.PostComment{ comment := internal.PostComment{
Message: msg, Message: msg,
@@ -292,7 +306,7 @@ func handleDisqusCreate(c *gin.Context) {
AuthorEmail: email, AuthorEmail: email,
AuthorName: name, AuthorName: name,
Identifier: identifier, Identifier: identifier,
IpAddress: c.ClientIP(), IPAddress: c.ClientIP(),
} }
postDetail, err := internal.PostCreate(&comment) postDetail, err := internal.PostCreate(&comment)
if err != nil { if err != nil {
@@ -312,7 +326,7 @@ func handleDisqusCreate(c *gin.Context) {
ID: postDetail.Response.ID, ID: postDetail.Response.ID,
Name: name, Name: name,
Parent: postDetail.Response.Parent, Parent: postDetail.Response.Parent,
Url: postDetail.Response.Author.ProfileUrl, URL: postDetail.Response.Author.ProfileURL,
Avatar: postDetail.Response.Author.Avatar.Cache, Avatar: postDetail.Response.Author.Avatar.Cache,
CreatedAtStr: tools.ConvertStr(postDetail.Response.CreatedAt), CreatedAtStr: tools.ConvertStr(postDetail.Response.CreatedAt),
Message: postDetail.Response.Message, Message: postDetail.Response.Message,

View File

@@ -2,6 +2,7 @@
package page package page
import ( import (
"io/fs"
"path/filepath" "path/filepath"
"text/template" "text/template"
@@ -17,10 +18,15 @@ var htmlTmpl *template.Template
func init() { func init() {
htmlTmpl = template.New("eiblog").Funcs(tools.TplFuncMap) htmlTmpl = template.New("eiblog").Funcs(tools.TplFuncMap)
root := filepath.Join(config.WorkDir, "website") root := filepath.Join(config.WorkDir, "website")
files := tools.ReadDirFiles(root, func(name string) bool { files := tools.ReadDirFiles(root, func(fi fs.FileInfo) bool {
name := fi.Name()
if name == ".DS_Store" { if name == ".DS_Store" {
return true return true
} }
// should not read template dir
if fi.IsDir() && name == "template" {
return true
}
return false return false
}) })
_, err := htmlTmpl.ParseFiles(files...) _, err := htmlTmpl.ParseFiles(files...)

View File

@@ -16,11 +16,12 @@ import (
// disqus api // disqus api
const ( const (
apiPostsCount = "https://disqus.com/api/3.0/threads/set.json" apiPostsCount = "https://disqus.com/api/3.0/threads/set.json"
apiPostsList = "https://disqus.com/api/3.0/threads/listPosts.json" apiPostsList = "https://disqus.com/api/3.0/threads/listPosts.json"
apiPostCreate = "https://disqus.com/api/3.0/posts/create.json" apiPostCreate = "https://disqus.com/api/3.0/posts/create.json"
apiPostApprove = "https://disqus.com/api/3.0/posts/approve.json" apiPostApprove = "https://disqus.com/api/3.0/posts/approve.json"
apiThreadCreate = "https://disqus.com/api/3.0/threads/create.json" apiThreadCreate = "https://disqus.com/api/3.0/threads/create.json"
apiThreadDetails = "https://disqus.com/api/3.0/threads/details.json"
) )
func checkDisqusConfig() error { func checkDisqusConfig() error {
@@ -95,8 +96,8 @@ func PostsCount(articles map[string]*model.Article) error {
return nil return nil
} }
// postsListResp 获取评论列表 // PostsListResp 获取评论列表
type postsListResp struct { type PostsListResp struct {
Cursor struct { Cursor struct {
HasNext bool HasNext bool
Next string Next string
@@ -113,7 +114,7 @@ type postDetail struct {
IsDeleted bool IsDeleted bool
Author struct { Author struct {
Name string Name string
ProfileUrl string ProfileURL string
Avatar struct { Avatar struct {
Cache string Cache string
} }
@@ -122,7 +123,7 @@ type postDetail struct {
} }
// PostsList 评论列表 // PostsList 评论列表
func PostsList(slug, cursor string) (*postsListResp, error) { func PostsList(slug, cursor string) (*PostsListResp, error) {
if err := checkDisqusConfig(); err != nil { if err := checkDisqusConfig(); err != nil {
return nil, err return nil, err
} }
@@ -148,7 +149,7 @@ func PostsList(slug, cursor string) (*postsListResp, error) {
return nil, errors.New(string(b)) return nil, errors.New(string(b))
} }
result := &postsListResp{} result := &PostsListResp{}
err = json.Unmarshal(b, result) err = json.Unmarshal(b, result)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -163,18 +164,19 @@ type PostComment struct {
Thread string Thread string
AuthorEmail string AuthorEmail string
AuthorName string AuthorName string
IpAddress string IPAddress string
Identifier string Identifier string
UserAgent string UserAgent string
} }
type postCreateResp struct { // PostCreateResp create comments resp
type PostCreateResp struct {
Code int Code int
Response postDetail Response postDetail
} }
// PostCreate 评论文章 // PostCreate 评论文章
func PostCreate(pc *PostComment) (*postCreateResp, error) { func PostCreate(pc *PostComment) (*PostCreateResp, error) {
if err := checkDisqusConfig(); err != nil { if err := checkDisqusConfig(); err != nil {
return nil, err return nil, err
} }
@@ -201,7 +203,7 @@ func PostCreate(pc *PostComment) (*postCreateResp, error) {
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, errors.New(string(b)) return nil, errors.New(string(b))
} }
result := &postCreateResp{} result := &PostCreateResp{}
err = json.Unmarshal(b, result) err = json.Unmarshal(b, result)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -294,3 +296,46 @@ func ThreadCreate(article *model.Article, btitle string) error {
article.Thread = result.Response.ID article.Thread = result.Response.ID
return nil return nil
} }
// threadDetailsResp thread info
type threadDetailsResp struct {
Code int
Response struct {
ID string
}
}
// ThreadDetails thread详细
func ThreadDetails(article *model.Article) error {
if err := checkDisqusConfig(); err != nil {
return err
}
vals := url.Values{}
vals.Set("api_key", config.Conf.EiBlogApp.Disqus.PublicKey)
vals.Set("access_token", config.Conf.EiBlogApp.Disqus.AccessToken)
vals.Set("forum", config.Conf.EiBlogApp.Disqus.ShortName)
vals.Set("thread:ident", "post-"+article.Slug)
resp, err := httpPost(apiThreadDetails, vals)
if err != nil {
return err
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return errors.New(string(b))
}
result := &threadDetailsResp{}
err = json.Unmarshal(b, result)
if err != nil {
return err
}
article.Thread = result.Response.ID
return nil
}

View File

@@ -49,7 +49,7 @@ func checkESConfig() error {
} }
// ElasticSearch 搜索文章 // ElasticSearch 搜索文章
func ElasticSearch(query string, size, from int) (*searchIndexResult, error) { func ElasticSearch(query string, size, from int) (*SearchIndexResult, error) {
if err := checkESConfig(); err != nil { if err := checkESConfig(); err != nil {
return nil, err return nil, err
} }
@@ -114,7 +114,7 @@ func ElasticAddIndex(article *model.Article) error {
img := tools.PickFirstImage(article.Content) img := tools.PickFirstImage(article.Content)
mapping := map[string]interface{}{ mapping := map[string]interface{}{
"title": article.Title, "title": article.Title,
"content": tools.IgnoreHtmlTag(article.Content), "content": tools.IgnoreHTMLTag(article.Content),
"slug": article.Slug, "slug": article.Slug,
"tag": article.Tags, "tag": article.Tags,
"img": img, "img": img,
@@ -241,8 +241,8 @@ func deleteIndexDocument(index, typ string, ids []string) error {
return nil return nil
} }
// searchIndexResult 查询结果 // SearchIndexResult 查询结果
type searchIndexResult struct { type SearchIndexResult struct {
Took float32 `json:"took"` Took float32 `json:"took"`
Hits struct { Hits struct {
Total int `json:"total"` Total int `json:"total"`
@@ -264,7 +264,7 @@ type searchIndexResult struct {
} }
// indexQueryDSL 语句查询文档 // indexQueryDSL 语句查询文档
func indexQueryDSL(index, typ string, size, from int, dsl []byte) (*searchIndexResult, error) { func indexQueryDSL(index, typ string, size, from int, dsl []byte) (*SearchIndexResult, error) {
rawurl := fmt.Sprintf("%s/%s/%s/_search?size=%d&from=%d", config.Conf.ESHost, rawurl := fmt.Sprintf("%s/%s/%s/_search?size=%d&from=%d", config.Conf.ESHost,
index, typ, size, from) index, typ, size, from)
resp, err := httpPost(rawurl, dsl) resp, err := httpPost(rawurl, dsl)
@@ -276,7 +276,7 @@ func indexQueryDSL(index, typ string, size, from int, dsl []byte) (*searchIndexR
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := &searchIndexResult{} result := &SearchIndexResult{}
err = json.Unmarshal(data, result) err = json.Unmarshal(data, result)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -20,6 +20,7 @@ type Article struct {
SerieID int `gorm:"column:serie_id;not null" bson:"serie_id"` // 专题ID SerieID int `gorm:"column:serie_id;not null" bson:"serie_id"` // 专题ID
Tags pq.StringArray `gorm:"column:tags;type:text[]" bson:"tags"` // tags Tags pq.StringArray `gorm:"column:tags;type:text[]" bson:"tags"` // tags
IsDraft bool `gorm:"column:is_draft;not null" bson:"is_draft"` // 是否是草稿 IsDraft bool `gorm:"column:is_draft;not null" bson:"is_draft"` // 是否是草稿
Thread string `gorm:"column:thread" bson:"thread"` // disqus thread
DeletedAt time.Time `gorm:"column:deleted_at;not null" bson:"deleted_at"` // 删除时间 DeletedAt time.Time `gorm:"column:deleted_at;not null" bson:"deleted_at"` // 删除时间
UpdatedAt time.Time `gorm:"column:updated_at;default:current_timestamp" bson:"updated_at"` // 更新时间 UpdatedAt time.Time `gorm:"column:updated_at;default:current_timestamp" bson:"updated_at"` // 更新时间
@@ -28,7 +29,6 @@ type Article struct {
Header string `gorm:"-" bson:"-"` // header Header string `gorm:"-" bson:"-"` // header
Excerpt string `gorm:"-" bson:"-"` // 预览信息 Excerpt string `gorm:"-" bson:"-"` // 预览信息
Desc string `gorm:"-" bson:"-"` // 描述 Desc string `gorm:"-" bson:"-"` // 描述
Thread string `gorm:"-" bson:"-"` // disqus thread
Prev *Article `gorm:"-" bson:"-"` // 上篇文章 Prev *Article `gorm:"-" bson:"-"` // 上篇文章
Next *Article `gorm:"-" bson:"-"` // 下篇文章 Next *Article `gorm:"-" bson:"-"` // 下篇文章
} }

View File

@@ -5,6 +5,7 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"io" "io"
"io/fs"
"io/ioutil" "io/ioutil"
"path" "path"
"regexp" "regexp"
@@ -22,13 +23,13 @@ func EncryptPasswd(name, pass string) string {
} }
// ReadDirFiles 读取目录 // ReadDirFiles 读取目录
func ReadDirFiles(dir string, filter func(name string) bool) (files []string) { func ReadDirFiles(dir string, filter func(fi fs.FileInfo) bool) (files []string) {
fileInfos, err := ioutil.ReadDir(dir) fileInfos, err := ioutil.ReadDir(dir)
if err != nil { if err != nil {
return return
} }
for _, fi := range fileInfos { for _, fi := range fileInfos {
if filter(fi.Name()) { if filter(fi) {
continue continue
} }
if fi.IsDir() { if fi.IsDir() {
@@ -42,19 +43,19 @@ func ReadDirFiles(dir string, filter func(name string) bool) (files []string) {
// 2016-10-22T07:03:01 // 2016-10-22T07:03:01
const ( const (
JUST_NOW = "几秒前" JustNow = "几秒前"
MINUTES_AGO = "%d分钟前" MinutesAgo = "%d分钟前"
HOURS_AGO = "%d小时前" HoursAgo = "%d小时前"
DAYS_AGO = "%d天前" DaysAgo = "%d天前"
MONTH_AGO = "%d月前" MonthAgo = "%d月前"
YEARS_AGO = "%d年前" YearsAgo = "%d年前"
) )
// ConvertStr 时间转换为间隔 // ConvertStr 时间转换为间隔
func ConvertStr(str string) string { func ConvertStr(str string) string {
t, err := time.ParseInLocation("2006-01-02T15:04:05", str, time.UTC) t, err := time.ParseInLocation("2006-01-02T15:04:05", str, time.UTC)
if err != nil { if err != nil {
return JUST_NOW return JustNow
} }
now := time.Now().UTC() now := time.Now().UTC()
y1, m1, d1 := t.Date() y1, m1, d1 := t.Date()
@@ -62,17 +63,17 @@ func ConvertStr(str string) string {
h1, mi1, s1 := t.Clock() h1, mi1, s1 := t.Clock()
h2, mi2, s2 := now.Clock() h2, mi2, s2 := now.Clock()
if y := y2 - y1; y > 1 || (y == 1 && m2-m1 >= 0) { if y := y2 - y1; y > 1 || (y == 1 && m2-m1 >= 0) {
return fmt.Sprintf(YEARS_AGO, y) return fmt.Sprintf(YearsAgo, y)
} else if m := y*12 + int(m2-m1); m > 1 || (m == 1 && d2-d1 >= 0) { } else if m := y*12 + int(m2-m1); m > 1 || (m == 1 && d2-d1 >= 0) {
return fmt.Sprintf(MONTH_AGO, m) return fmt.Sprintf(MonthAgo, m)
} else if d := m*dayIn(y1, m1) + d2 - d1; d > 1 || (d == 1 && h2-h1 >= 0) { } else if d := m*dayIn(y1, m1) + d2 - d1; d > 1 || (d == 1 && h2-h1 >= 0) {
return fmt.Sprintf(DAYS_AGO, d) return fmt.Sprintf(DaysAgo, d)
} else if h := d*24 + h2 - h1; h > 1 || (h == 1 && mi2-mi1 >= 0) { } else if h := d*24 + h2 - h1; h > 1 || (h == 1 && mi2-mi1 >= 0) {
return fmt.Sprintf(HOURS_AGO, h) return fmt.Sprintf(HoursAgo, h)
} else if mi := h*60 + mi2 - mi1; mi > 1 || (mi == 1 && s2-s1 >= 0) { } else if mi := h*60 + mi2 - mi1; mi > 1 || (mi == 1 && s2-s1 >= 0) {
return fmt.Sprintf(MINUTES_AGO, mi) return fmt.Sprintf(MinutesAgo, mi)
} }
return JUST_NOW return JustNow
} }
// dayIn 获取天数 // dayIn 获取天数
@@ -120,8 +121,8 @@ var (
regexpEnter = regexp.MustCompile(`\s+`) regexpEnter = regexp.MustCompile(`\s+`)
) )
// IgnoreHtmlTag 去掉 html tag // IgnoreHTMLTag 去掉 html tag
func IgnoreHtmlTag(src string) string { func IgnoreHTMLTag(src string) string {
// 去除所有尖括号内的HTML代码 // 去除所有尖括号内的HTML代码
src = regexpBrackets.ReplaceAllString(src, "") src = regexpBrackets.ReplaceAllString(src, "")
// 去除换行符 // 去除换行符