This commit is contained in:
tamakyi
2026-09-09 19:08:59 +08:00
parent 4e6a743179
commit 5f555b447d
2 changed files with 45 additions and 0 deletions
+44
View File
@@ -291,6 +291,7 @@ func (e *Engine) LoadAll() {
continue continue
} }
e.states[name] = &repoState{cfg: cfg, status: "idle"} e.states[name] = &repoState{cfg: cfg, status: "idle"}
e.restoreLastSync(e.states[name])
} }
} }
@@ -353,6 +354,44 @@ func rotateStatIfNeeded(path string, maxLines int) bool {
return true return true
} }
// restoreLastSync 从统计 CSV 的最后一条记录恢复 lastSync,使重启后界面不再显示「从未同步」。
func (e *Engine) restoreLastSync(s *repoState) {
path := filepath.Join(e.statsDir, s.cfg.Name+".csv")
f, err := os.Open(path)
if err != nil {
return
}
defer f.Close()
recs, err := csv.NewReader(f).ReadAll()
if err != nil || len(recs) < 2 {
return
}
var ts, raw string
for _, rec := range recs[1:] {
if len(rec) < 3 {
continue
}
ts, raw = rec[0], rec[2]
}
if ts == "" {
return
}
result := raw
switch raw {
case "success":
result = "ok"
case "failed":
result = "error"
}
detail := map[string]string{"ok": "同步完成", "error": "同步失败", "conflict": "存在冲突"}[result]
if detail == "" {
detail = "上次同步"
}
s.mu.Lock()
s.lastSync = &SyncResult{Time: ts, Result: result, Detail: detail}
s.mu.Unlock()
}
func firstRemoteName(cfg *RepoConfig) string { func firstRemoteName(cfg *RepoConfig) string {
if len(cfg.Remotes) > 0 { if len(cfg.Remotes) > 0 {
return cfg.Remotes[0].Name return cfg.Remotes[0].Name
@@ -576,6 +615,7 @@ func (e *Engine) setFail(s *repoState, msg string) {
s.lastError = msg s.lastError = msg
s.lastSync = &SyncResult{Time: now, Result: "error", Detail: msg} s.lastSync = &SyncResult{Time: now, Result: "error", Detail: msg}
s.mu.Unlock() s.mu.Unlock()
e.stat(s, "sync", "error", 0)
e.logf(s, "error", "%s", msg) e.logf(s, "error", "%s", msg)
e.pushStatus(s) e.pushStatus(s)
} }
@@ -587,6 +627,7 @@ func (e *Engine) setOK(s *repoState, detail string) {
s.lastError = "" s.lastError = ""
s.lastSync = &SyncResult{Time: now, Result: "ok", Detail: detail} s.lastSync = &SyncResult{Time: now, Result: "ok", Detail: detail}
s.mu.Unlock() s.mu.Unlock()
e.stat(s, "sync", "ok", 0)
e.pushStatus(s) e.pushStatus(s)
} }
@@ -915,6 +956,7 @@ func (e *Engine) pullRemote(s *repoState, cfg *RepoConfig, remote string, n int)
s.lastError = "拉取产生冲突,等待在冲突处理台解决" s.lastError = "拉取产生冲突,等待在冲突处理台解决"
s.lastSync = &SyncResult{Time: now, Result: "conflict", Detail: s.lastError} s.lastSync = &SyncResult{Time: now, Result: "conflict", Detail: s.lastError}
s.mu.Unlock() s.mu.Unlock()
e.stat(s, "sync", "conflict", 0)
e.stat(s, "pull", "conflict", n) e.stat(s, "pull", "conflict", n)
e.logf(s, "error", "拉取产生冲突:%s(请在详情 → 冲突中处理)", strings.Join(files, ", ")) e.logf(s, "error", "拉取产生冲突:%s(请在详情 → 冲突中处理)", strings.Join(files, ", "))
e.pushStatus(s) e.pushStatus(s)
@@ -955,6 +997,7 @@ func (e *Engine) ForcePush(name string) error {
s.lastError = "" s.lastError = ""
s.lastSync = &SyncResult{Time: time.Now().Format("2006-01-02 15:04:05"), Result: "ok", Detail: "强制推送完成"} s.lastSync = &SyncResult{Time: time.Now().Format("2006-01-02 15:04:05"), Result: "ok", Detail: "强制推送完成"}
s.mu.Unlock() s.mu.Unlock()
e.stat(s, "sync", "ok", 0)
e.pushStatus(s) e.pushStatus(s)
return nil return nil
} }
@@ -975,6 +1018,7 @@ func (e *Engine) AbortPush(name string) error {
s.status = "ok" s.status = "ok"
s.lastError = "用户放弃强制推送" s.lastError = "用户放弃强制推送"
s.lastSync = &SyncResult{Time: time.Now().Format("2006-01-02 15:04:05"), Result: "ok", Detail: "放弃强制推送,状态已清除"} s.lastSync = &SyncResult{Time: time.Now().Format("2006-01-02 15:04:05"), Result: "ok", Detail: "放弃强制推送,状态已清除"}
e.stat(s, "sync", "ok", 0)
e.logf(s, "warn", "放弃强制推送") e.logf(s, "warn", "放弃强制推送")
e.pushStatus(s) e.pushStatus(s)
return nil return nil
+1
View File
@@ -961,6 +961,7 @@ function dateStr(d) {
function loadStats(name) { function loadStats(name) {
api(`/api/repos/${name}/stats`).then(rows => { api(`/api/repos/${name}/stats`).then(rows => {
rows = rows.filter(r => r.action !== 'sync');
const days = []; const days = [];
for (let i = 29; i >= 0; i--) { for (let i = 29; i >= 0; i--) {
const d = new Date(); const d = new Date();