173 lines
4.6 KiB
Go
173 lines
4.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"github.com/ArtalkJS/Artalk/internal/config"
|
|
"github.com/ArtalkJS/Artalk/internal/core"
|
|
"github.com/ArtalkJS/Artalk/internal/entity"
|
|
"github.com/ArtalkJS/Artalk/internal/i18n"
|
|
"github.com/ArtalkJS/Artalk/internal/utils"
|
|
"github.com/ArtalkJS/Artalk/server/common"
|
|
"github.com/gofiber/fiber/v2"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ParamsStat struct {
|
|
Type string `form:"type" validate:"required"`
|
|
|
|
SiteName string
|
|
PageKeys string `form:"page_keys"`
|
|
|
|
Limit int `form:"limit"`
|
|
|
|
SiteID uint
|
|
SiteAll bool
|
|
}
|
|
|
|
// @Summary Statistics
|
|
// @Description Get the statistics of various data analysed
|
|
// @Tags Statistics
|
|
// @Param type formData string true "the type of statistics" Enums(latest_comments, latest_pages, pv_most_pages, comment_most_pages, page_pv, site_pv, page_comment, site_comment, rand_comments, rand_pages)
|
|
// @Param page_keys formData string false "multiple page keys separated by commas"
|
|
// @Param site_name formData string false "the site name of your content scope"
|
|
// @Param limit formData int false "the amount of items you want"
|
|
// @Success 200 {object} common.JSONResult
|
|
// @Router /stat [post]
|
|
func Stat(app *core.App, router fiber.Router) {
|
|
router.Post("/stat", func(c *fiber.Ctx) error {
|
|
var p ParamsStat
|
|
if isOK, resp := common.ParamsDecode(c, &p); !isOK {
|
|
return resp
|
|
}
|
|
|
|
// use site
|
|
common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll)
|
|
|
|
// Limit 限定
|
|
if p.Limit <= 0 {
|
|
p.Limit = 5
|
|
}
|
|
if p.Limit > 100 {
|
|
p.Limit = 100
|
|
}
|
|
|
|
// 公共查询规则
|
|
QueryPages := func(d *gorm.DB) *gorm.DB {
|
|
return d.Model(&entity.Page{}).Where("site_name = ?", p.SiteName)
|
|
}
|
|
QueryComments := func(d *gorm.DB) *gorm.DB {
|
|
return d.Model(&entity.Comment{}).Where("site_name = ? AND is_pending = ?", p.SiteName, false)
|
|
}
|
|
QueryOrderRand := func(d *gorm.DB) *gorm.DB {
|
|
if app.Conf().DB.Type == config.TypeSQLite {
|
|
return d.Order("RANDOM()") // SQLite case
|
|
} else {
|
|
return d.Order("RAND()")
|
|
}
|
|
}
|
|
|
|
switch p.Type {
|
|
case "latest_comments":
|
|
// 最新评论
|
|
var comments []entity.Comment
|
|
app.Dao().DB().Scopes(QueryComments).
|
|
Order("created_at DESC").
|
|
Limit(p.Limit).
|
|
Find(&comments)
|
|
|
|
return common.RespData(c, app.Dao().CookAllComments(comments))
|
|
|
|
case "latest_pages":
|
|
// 最新页面
|
|
var pages []entity.Page
|
|
app.Dao().DB().Scopes(QueryPages).
|
|
Order("created_at DESC").
|
|
Limit(p.Limit).
|
|
Find(&pages)
|
|
|
|
return common.RespData(c, app.Dao().CookAllPages(pages))
|
|
|
|
case "pv_most_pages":
|
|
// PV 数最多的页面
|
|
var pages []entity.Page
|
|
app.Dao().DB().Scopes(QueryPages).
|
|
Order("pv DESC").
|
|
Limit(p.Limit).
|
|
Find(&pages)
|
|
|
|
return common.RespData(c, app.Dao().CookAllPages(pages))
|
|
|
|
case "comment_most_pages":
|
|
// 评论数最多的页面
|
|
var pages []entity.Page
|
|
app.Dao().DB().Raw(
|
|
"SELECT * FROM pages p WHERE p.site_name = ? ORDER BY (SELECT COUNT(*) FROM comments c WHERE c.page_key = p.key AND c.is_pending = ?) DESC LIMIT ?",
|
|
p.SiteName, false, p.Limit,
|
|
).Find(&pages)
|
|
|
|
return common.RespData(c, app.Dao().CookAllPages(pages))
|
|
|
|
case "page_pv":
|
|
// 查询页面的 PV 数
|
|
keys := utils.SplitAndTrimSpace(p.PageKeys, ",")
|
|
pvs := map[string]int{}
|
|
for _, k := range keys {
|
|
page := app.Dao().FindPage(k, p.SiteName)
|
|
if !page.IsEmpty() {
|
|
pvs[k] = page.PV
|
|
} else {
|
|
pvs[k] = 0
|
|
}
|
|
}
|
|
|
|
return common.RespData(c, pvs)
|
|
|
|
case "site_pv":
|
|
// 全站 PV 数
|
|
var pv int64
|
|
app.Dao().DB().Raw("SELECT SUM(pv) FROM pages WHERE site_name = ?", p.SiteName).Row().Scan(&pv)
|
|
|
|
return common.RespData(c, pv)
|
|
|
|
case "page_comment":
|
|
// 查询页面的评论数
|
|
keys := utils.SplitAndTrimSpace(p.PageKeys, ",")
|
|
counts := map[string]int64{}
|
|
for _, k := range keys {
|
|
var count int64
|
|
app.Dao().DB().Scopes(QueryComments).Where("page_key = ?", k).Count(&count)
|
|
|
|
counts[k] = count
|
|
}
|
|
|
|
return common.RespData(c, counts)
|
|
|
|
case "site_comment":
|
|
// 全站评论数
|
|
var count int64
|
|
app.Dao().DB().Scopes(QueryComments).Count(&count)
|
|
|
|
return common.RespData(c, count)
|
|
|
|
case "rand_comments":
|
|
// 随机评论
|
|
var comments []entity.Comment
|
|
app.Dao().DB().Scopes(QueryComments, QueryOrderRand).
|
|
Limit(p.Limit).
|
|
Find(&comments)
|
|
|
|
return common.RespData(c, app.Dao().CookAllComments(comments))
|
|
|
|
case "rand_pages":
|
|
// 随机页面
|
|
var pages []entity.Page
|
|
app.Dao().DB().Scopes(QueryPages, QueryOrderRand).
|
|
Limit(p.Limit).
|
|
Find(&pages)
|
|
|
|
return common.RespData(c, app.Dao().CookAllPages(pages))
|
|
}
|
|
|
|
return common.RespError(c, i18n.T("Invalid {{name}}", Map{"name": i18n.T("Type")}))
|
|
})
|
|
}
|