Files
ainovel-clients/state/relationships.go
voocel 27bd85ef90 init
2026-03-07 21:25:55 +08:00

71 lines
1.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package state
import (
"fmt"
"os"
"strings"
"github.com/voocel/ainovel-cli/domain"
)
// SaveRelationships 全量写入 relationship_state.json + relationship_state.md。
func (s *Store) SaveRelationships(entries []domain.RelationshipEntry) error {
if err := s.writeJSON("relationship_state.json", entries); err != nil {
return err
}
return s.writeMarkdown("relationship_state.md", renderRelationships(entries))
}
// LoadRelationships 读取人物关系状态。
func (s *Store) LoadRelationships() ([]domain.RelationshipEntry, error) {
var entries []domain.RelationshipEntry
if err := s.readJSON("relationship_state.json", &entries); err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, err
}
return entries, nil
}
// UpdateRelationships 合并关系变化。相同人物对的关系会被更新为最新值。
func (s *Store) UpdateRelationships(changes []domain.RelationshipEntry) error {
existing, err := s.LoadRelationships()
if err != nil {
return err
}
// 用 pair key 索引
idx := make(map[string]int, len(existing))
for i, e := range existing {
idx[pairKey(e.CharacterA, e.CharacterB)] = i
}
for _, c := range changes {
key := pairKey(c.CharacterA, c.CharacterB)
if i, ok := idx[key]; ok {
existing[i].Relation = c.Relation
existing[i].Chapter = c.Chapter
} else {
idx[key] = len(existing)
existing = append(existing, c)
}
}
return s.SaveRelationships(existing)
}
func pairKey(a, b string) string {
if a > b {
a, b = b, a
}
return a + "|" + b
}
func renderRelationships(entries []domain.RelationshipEntry) string {
var b strings.Builder
b.WriteString("# 人物关系\n\n")
for _, e := range entries {
fmt.Fprintf(&b, "- **%s ↔ %s**%s第 %d 章)\n",
e.CharacterA, e.CharacterB, e.Relation, e.Chapter)
}
return b.String()
}