feat: Studio 概览/分析补上阅读量 + 详情页 meta 行改版
- StudioOverview 新增 TotalViews 字段,GetOverviewByUserID 查询含 SUM(views_count) - 新增 ViewTrendStore 接口和 AggregateViewsByAuthor,UNION ALL 合并已登录+访客阅读日志按日期聚合 - 数据分析页面新增阅读量趋势折线图(绿色,Chart.js) - 概览和数据分析页面新增总阅读量统计卡片 - 详情页 meta 行改为标签格式:作者/阅读/点赞/收藏/评论/发布时间 - 移除详情页公开状态徽章,已锁定+理由仅作者可见
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"time"
|
||||
|
||||
"metazone.cc/metalab/internal/model"
|
||||
"metazone.cc/metalab/internal/service"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
@ -40,10 +41,11 @@ type overviewRow struct {
|
||||
PendingCount int64
|
||||
ApprovedCount int64
|
||||
RejectedCount int64
|
||||
TotalViews int64
|
||||
}
|
||||
|
||||
// GetOverviewByUserID 用单次 GROUP BY 查询聚合用户各状态文章数
|
||||
func (r *PostRepo) GetOverviewByUserID(userID uint) (totalPosts, draftCount, pendingCount, approvedCount, rejectedCount int64, err error) {
|
||||
// GetOverviewByUserID 用单次 GROUP BY 查询聚合用户各状态文章数 + 总阅读量
|
||||
func (r *PostRepo) GetOverviewByUserID(userID uint) (totalPosts, draftCount, pendingCount, approvedCount, rejectedCount, totalViews int64, err error) {
|
||||
var row overviewRow
|
||||
err = r.db.Model(&model.Post{}).
|
||||
Select(`
|
||||
@ -51,11 +53,12 @@ func (r *PostRepo) GetOverviewByUserID(userID uint) (totalPosts, draftCount, pen
|
||||
COALESCE(SUM(CASE WHEN status = 'draft' THEN 1 ELSE 0 END), 0) AS draft_count,
|
||||
COALESCE(SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END), 0) AS pending_count,
|
||||
COALESCE(SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END), 0) AS approved_count,
|
||||
COALESCE(SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END), 0) AS rejected_count
|
||||
COALESCE(SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END), 0) AS rejected_count,
|
||||
COALESCE(SUM(views_count), 0) AS total_views
|
||||
`).
|
||||
Where("user_id = ? AND deleted_at IS NULL", userID).
|
||||
Scan(&row).Error
|
||||
return row.TotalPosts, row.DraftCount, row.PendingCount, row.ApprovedCount, row.RejectedCount, err
|
||||
return row.TotalPosts, row.DraftCount, row.PendingCount, row.ApprovedCount, row.RejectedCount, row.TotalViews, err
|
||||
}
|
||||
|
||||
// readCooldown 两次阅读记录最小间隔
|
||||
@ -106,3 +109,26 @@ func (r *PostRepo) IncrementViewsCount(postID uint) error {
|
||||
return r.db.Model(&model.Post{}).Where("id = ?", postID).
|
||||
Update("views_count", gorm.Expr("views_count + 1")).Error
|
||||
}
|
||||
|
||||
// AggregateViewsByAuthor 按日期聚合阅读量(作者所有文章在时间段内的阅读记录,含已登录+访客)
|
||||
func (r *PostRepo) AggregateViewsByAuthor(userID uint, since string) ([]service.TrendPoint, error) {
|
||||
var results []service.TrendPoint
|
||||
err := r.db.Raw(`
|
||||
SELECT TO_CHAR(t.read_at, 'YYYY-MM-DD') AS date, COUNT(*) AS value
|
||||
FROM (
|
||||
SELECT prl.read_at FROM post_read_logs prl
|
||||
JOIN posts p ON p.id = prl.post_id
|
||||
WHERE p.user_id = ? AND prl.read_at >= ?
|
||||
UNION ALL
|
||||
SELECT pgrl.read_at FROM post_guest_read_logs pgrl
|
||||
JOIN posts p ON p.id = pgrl.post_id
|
||||
WHERE p.user_id = ? AND pgrl.read_at >= ?
|
||||
) t
|
||||
GROUP BY TO_CHAR(t.read_at, 'YYYY-MM-DD')
|
||||
ORDER BY date ASC
|
||||
`, userID, since, userID, since).Scan(&results).Error
|
||||
if results == nil {
|
||||
results = []service.TrendPoint{}
|
||||
}
|
||||
return results, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user