feat(nav): 常用服务改为纯访问频次 top-5,取消 Gitea 置顶

用户要求:不要固定置顶 Gitea,且每个服务都应归到准确描述其功能的分组里。

- history-server/main.go:删除「强制 Gitea/代码托管置顶」逻辑(含 isCodeHostVal
  参与的首位组装),改为按访问频次取前 5;顶部说明同步更正
- 文档:README / AGENTS.md 里"(Gitea 置顶)"的描述改为"不置顶任何服务"
- 现场分组调整:新建「代码托管」分组并把 Gitea 归入(此前它只存在于
  系统管理的 常用服务 里,等于没有功能归属)

go vet / go test 通过。
This commit is contained in:
HomeDash Bot
2026-09-12 12:27:35 +08:00
parent 7c3054f14a
commit a9845f1fba
3 changed files with 10 additions and 23 deletions

View File

@ -181,7 +181,7 @@ curl -s -X POST -H "Authorization: Bearer $TOK" "$A/gateway/apply"
curl -s -X POST -H "Authorization: Bearer $TOK" -H 'Content-Type: application/json' \
-d '{"name":"常用服务"}' "$A/section"
> ⚠️ **两个分组是系统管理的,不要往里手工加条目**:
> - `常用服务`:按**访问频次**自动取前 5(Gitea 固定置顶),服务端重建
> - `常用服务`:按**访问频次**自动取前 5(**不置顶任何服务**),服务端重建
> - `历史访问`:按浏览器同步的浏览记录重建(安装入口由它自己放在首位)
>
> 因此 `navEnabled` 的 `navSection` 必须指向**用户分组**(如 `AI & 工具`、`系统管理`)。

View File

@ -642,7 +642,7 @@ curl -s http://127.0.0.1:18080/api/schema | jq # 人读:items + resourc
echo "$code"
```
> **注意 `常用服务` 与 `历史访问` 是系统管理的分组**:前者按访问频次自动取前 5(Gitea 置顶),
> **注意 `常用服务` 与 `历史访问` 是系统管理的分组**:前者按访问频次自动取前 5(**不置顶任何服务**),
> 后者按浏览记录重建。新增服务要放进用户分组(如 `AI & 工具`);`navEnabled` 的 `navSection`
> 若指向 `常用服务`,条目会在下次重建时被挤掉。

View File

@ -322,7 +322,7 @@ func extensionInstallItem() map[string]any {
// rebuildDashySections 读 conf.yml:
// 1. 收集除「历史访问」外所有导航项
// 2. 按各导航 host 在 history 的累计访问统计
// 3. 「常用服务」= 访问最高的 4 个导航(Gitea/代码托管恒置顶)
// 3. 「常用服务」= 访问频次最高的 5 个导航(不置顶任何服务)
// 4. 「历史访问」= 非导航 host 的 top 20
func rebuildDashySections() {
// 序列化重建:同步请求、启动、以及 favicon 抓完后的重试都会调到这里。
@ -458,26 +458,13 @@ func rebuildDashySections() {
candidates = uniq
}
// 强制 Gitea/代码托管置顶:host 或标题含 gitea/git/code/代码/仓库
// 代码托管识别(独立函数便于单测)
var top []cand
var codeHost *cand
rest := make([]cand, 0, len(candidates))
for i := range candidates {
if codeHost == nil && isCodeHostVal(candidates[i].nav.title, candidates[i].host, candidates[i].nav.url) {
codeHost = &candidates[i]
} else {
rest = append(rest, candidates[i])
}
}
top = append(top, rest...)
// 组装:Gitea 第一(若存在),再加访问最高的其余导航,凑满 4
finalNavs := make([]dashyNav, 0, 4)
if codeHost != nil {
finalNavs = append(finalNavs, codeHost.nav)
}
for _, c := range top {
if len(finalNavs) >= 4 {
// 「常用服务」= 纯访问频次前 N,**不置顶任何服务**。
// 曾有一版把 Gitea/代码托管强制放第一位;用户要求取消:每个服务都应归在
// 准确描述其功能的分组里,常用服务只做频次聚合。
const favTopN = 5
finalNavs := make([]dashyNav, 0, favTopN)
for _, c := range candidates {
if len(finalNavs) >= favTopN {
break
}
finalNavs = append(finalNavs, c.nav)