77 lines
1.9 KiB
Go
77 lines
1.9 KiB
Go
package state
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/voocel/ainovel-cli/domain"
|
|
)
|
|
|
|
// SaveForeshadowLedger 全量写入 foreshadow_ledger.json + foreshadow_ledger.md。
|
|
func (s *Store) SaveForeshadowLedger(entries []domain.ForeshadowEntry) error {
|
|
if err := s.writeJSON("foreshadow_ledger.json", entries); err != nil {
|
|
return err
|
|
}
|
|
return s.writeMarkdown("foreshadow_ledger.md", renderForeshadow(entries))
|
|
}
|
|
|
|
// LoadForeshadowLedger 读取伏笔账本。
|
|
func (s *Store) LoadForeshadowLedger() ([]domain.ForeshadowEntry, error) {
|
|
var entries []domain.ForeshadowEntry
|
|
if err := s.readJSON("foreshadow_ledger.json", &entries); err != nil {
|
|
if os.IsNotExist(err) {
|
|
return nil, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
return entries, nil
|
|
}
|
|
|
|
// UpdateForeshadow 批量应用伏笔增量操作。
|
|
func (s *Store) UpdateForeshadow(chapter int, updates []domain.ForeshadowUpdate) error {
|
|
entries, err := s.LoadForeshadowLedger()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
idx := make(map[string]int, len(entries))
|
|
for i, e := range entries {
|
|
idx[e.ID] = i
|
|
}
|
|
for _, u := range updates {
|
|
switch u.Action {
|
|
case "plant":
|
|
entries = append(entries, domain.ForeshadowEntry{
|
|
ID: u.ID,
|
|
Description: u.Description,
|
|
PlantedAt: chapter,
|
|
Status: "planted",
|
|
})
|
|
case "advance":
|
|
if i, ok := idx[u.ID]; ok {
|
|
entries[i].Status = "advanced"
|
|
}
|
|
case "resolve":
|
|
if i, ok := idx[u.ID]; ok {
|
|
entries[i].Status = "resolved"
|
|
entries[i].ResolvedAt = chapter
|
|
}
|
|
}
|
|
}
|
|
return s.SaveForeshadowLedger(entries)
|
|
}
|
|
|
|
func renderForeshadow(entries []domain.ForeshadowEntry) string {
|
|
var b strings.Builder
|
|
b.WriteString("# 伏笔账本\n\n")
|
|
for _, e := range entries {
|
|
status := e.Status
|
|
if e.ResolvedAt > 0 {
|
|
status = fmt.Sprintf("已回收(第 %d 章)", e.ResolvedAt)
|
|
}
|
|
fmt.Fprintf(&b, "- **[%s]** %s — 埋设于第 %d 章,状态:%s\n",
|
|
e.ID, e.Description, e.PlantedAt, status)
|
|
}
|
|
return b.String()
|
|
}
|