Update mini program development documentation and enhance user interface elements
- Added a new entry for the latest mini program development rules and APIs in the evolution index. - Updated the skill documentation to include guidelines on privacy authorization and capability detection. - Modified the read and settings pages to improve user experience with new input styles and layout adjustments. - Implemented user-select functionality for text elements in the read page to enhance interactivity. - Refined CSS styles for better responsiveness and visual consistency across various components.
This commit is contained in:
@@ -3,7 +3,6 @@ package handler
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"net/http"
|
||||
"sort"
|
||||
"time"
|
||||
@@ -87,7 +86,9 @@ func computeArticleRankingSections(db *gorm.DB) ([]sectionListItem, error) {
|
||||
return sections, nil
|
||||
}
|
||||
|
||||
// computeSectionsWithHotScore 内部:计算 hotScore,可选设置 isPinned
|
||||
// computeSectionsWithHotScore 内部:按排名分算法计算 hotScore
|
||||
// 热度积分 = 阅读权重×阅读排名分 + 新度权重×新度排名分 + 付款权重×付款排名分
|
||||
// 阅读量前20名: 第1名=20分...第20名=1分;最近更新前30篇: 第1名=30分...第30名=1分;付款数前20名: 第1名=20分...第20名=1分
|
||||
func computeSectionsWithHotScore(db *gorm.DB, setPinned bool) ([]sectionListItem, error) {
|
||||
var rows []model.Chapter
|
||||
if err := db.Select(listSelectCols).Order("sort_order ASC, id ASC").Find(&rows).Error; err != nil {
|
||||
@@ -123,7 +124,7 @@ func computeSectionsWithHotScore(db *gorm.DB, setPinned bool) ([]sectionListItem
|
||||
payCountMap[r.ProductID] = r.Cnt
|
||||
}
|
||||
}
|
||||
readWeight, payWeight, recencyWeight := 0.5, 0.3, 0.2
|
||||
readWeight, payWeight, recencyWeight := 0.1, 0.4, 0.5 // 默认与截图一致
|
||||
var cfg model.SystemConfig
|
||||
if err := db.Where("config_key = ?", "article_ranking_weights").First(&cfg).Error; err == nil && len(cfg.ConfigValue) > 0 {
|
||||
var v struct {
|
||||
@@ -132,13 +133,13 @@ func computeSectionsWithHotScore(db *gorm.DB, setPinned bool) ([]sectionListItem
|
||||
PayWeight float64 `json:"payWeight"`
|
||||
}
|
||||
if err := json.Unmarshal(cfg.ConfigValue, &v); err == nil {
|
||||
if v.ReadWeight > 0 {
|
||||
if v.ReadWeight >= 0 {
|
||||
readWeight = v.ReadWeight
|
||||
}
|
||||
if v.PayWeight > 0 {
|
||||
if v.PayWeight >= 0 {
|
||||
payWeight = v.PayWeight
|
||||
}
|
||||
if v.RecencyWeight > 0 {
|
||||
if v.RecencyWeight >= 0 {
|
||||
recencyWeight = v.RecencyWeight
|
||||
}
|
||||
}
|
||||
@@ -156,7 +157,52 @@ func computeSectionsWithHotScore(db *gorm.DB, setPinned bool) ([]sectionListItem
|
||||
pinnedSet[id] = true
|
||||
}
|
||||
}
|
||||
now := time.Now()
|
||||
|
||||
// 1. 阅读量排名:按 readCount 降序,前20名得 20~1 分
|
||||
type idCnt struct {
|
||||
id string
|
||||
cnt int64
|
||||
}
|
||||
readRank := make([]idCnt, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
readRank = append(readRank, idCnt{r.ID, readCountMap[r.ID]})
|
||||
}
|
||||
sort.Slice(readRank, func(i, j int) bool { return readRank[i].cnt > readRank[j].cnt })
|
||||
readRankScoreMap := make(map[string]float64)
|
||||
for i := 0; i < len(readRank) && i < 20; i++ {
|
||||
readRankScoreMap[readRank[i].id] = float64(20 - i)
|
||||
}
|
||||
|
||||
// 2. 新度排名:按 updated_at 降序(最近更新在前),前30篇得 30~1 分
|
||||
recencyRank := make([]struct {
|
||||
id string
|
||||
updatedAt time.Time
|
||||
}, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
recencyRank = append(recencyRank, struct {
|
||||
id string
|
||||
updatedAt time.Time
|
||||
}{r.ID, r.UpdatedAt})
|
||||
}
|
||||
sort.Slice(recencyRank, func(i, j int) bool {
|
||||
return recencyRank[i].updatedAt.After(recencyRank[j].updatedAt)
|
||||
})
|
||||
recencyRankScoreMap := make(map[string]float64)
|
||||
for i := 0; i < len(recencyRank) && i < 30; i++ {
|
||||
recencyRankScoreMap[recencyRank[i].id] = float64(30 - i)
|
||||
}
|
||||
|
||||
// 3. 付款数排名:按 payCount 降序,前20名得 20~1 分
|
||||
payRank := make([]idCnt, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
payRank = append(payRank, idCnt{r.ID, payCountMap[r.ID]})
|
||||
}
|
||||
sort.Slice(payRank, func(i, j int) bool { return payRank[i].cnt > payRank[j].cnt })
|
||||
payRankScoreMap := make(map[string]float64)
|
||||
for i := 0; i < len(payRank) && i < 20; i++ {
|
||||
payRankScoreMap[payRank[i].id] = float64(20 - i)
|
||||
}
|
||||
|
||||
sections := make([]sectionListItem, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
price := 1.0
|
||||
@@ -165,15 +211,15 @@ func computeSectionsWithHotScore(db *gorm.DB, setPinned bool) ([]sectionListItem
|
||||
}
|
||||
readCnt := readCountMap[r.ID]
|
||||
payCnt := payCountMap[r.ID]
|
||||
recencyScore := 0.0
|
||||
if !r.UpdatedAt.IsZero() {
|
||||
days := now.Sub(r.UpdatedAt).Hours() / 24
|
||||
recencyScore = math.Max(0, (30-days)/30)
|
||||
if recencyScore > 1 {
|
||||
recencyScore = 1
|
||||
}
|
||||
readRankScore := readRankScoreMap[r.ID]
|
||||
recencyRankScore := recencyRankScoreMap[r.ID]
|
||||
payRankScore := payRankScoreMap[r.ID]
|
||||
// 热度积分 = 阅读权重×阅读排名分 + 新度权重×新度排名分 + 付款权重×付款排名分
|
||||
hot := readWeight*readRankScore + recencyWeight*recencyRankScore + payWeight*payRankScore
|
||||
// 若章节有手动覆盖的 hot_score(>0),则优先使用
|
||||
if r.HotScore > 0 {
|
||||
hot = float64(r.HotScore)
|
||||
}
|
||||
hot := float64(readCnt)*readWeight + float64(payCnt)*payWeight + recencyScore*recencyWeight
|
||||
item := sectionListItem{
|
||||
ID: r.ID,
|
||||
MID: r.MID,
|
||||
|
||||
Reference in New Issue
Block a user