feat: 支持长篇小说分层架构(卷/弧/章三级结构)
This commit is contained in:
@@ -44,3 +44,93 @@ func (s *Store) LoadRecentSummaries(current, count int) ([]domain.ChapterSummary
|
||||
func (s *Store) LoadAllSummaries(current int) ([]domain.ChapterSummary, error) {
|
||||
return s.LoadRecentSummaries(current, current)
|
||||
}
|
||||
|
||||
// SaveArcSummary 保存弧级摘要到 summaries/arc-v{vol}a{arc}.json。
|
||||
func (s *Store) SaveArcSummary(sum domain.ArcSummary) error {
|
||||
return s.writeJSON(fmt.Sprintf("summaries/arc-v%02da%02d.json", sum.Volume, sum.Arc), sum)
|
||||
}
|
||||
|
||||
// LoadArcSummary 读取指定弧的摘要。
|
||||
func (s *Store) LoadArcSummary(volume, arc int) (*domain.ArcSummary, error) {
|
||||
var sum domain.ArcSummary
|
||||
if err := s.readJSON(fmt.Sprintf("summaries/arc-v%02da%02d.json", volume, arc), &sum); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &sum, nil
|
||||
}
|
||||
|
||||
// LoadArcSummaries 加载一卷内所有已有弧摘要。
|
||||
// 从分层大纲获取实际弧数,无分层大纲时扫描到首个缺失为止。
|
||||
func (s *Store) LoadArcSummaries(volume int) ([]domain.ArcSummary, error) {
|
||||
maxArc := s.arcCountForVolume(volume)
|
||||
var result []domain.ArcSummary
|
||||
for arc := 1; arc <= maxArc; arc++ {
|
||||
sum, err := s.LoadArcSummary(volume, arc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sum != nil {
|
||||
result = append(result, *sum)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SaveVolumeSummary 保存卷级摘要到 summaries/vol-v{vol}.json。
|
||||
func (s *Store) SaveVolumeSummary(sum domain.VolumeSummary) error {
|
||||
return s.writeJSON(fmt.Sprintf("summaries/vol-v%02d.json", sum.Volume), sum)
|
||||
}
|
||||
|
||||
// LoadVolumeSummary 读取指定卷的摘要。
|
||||
func (s *Store) LoadVolumeSummary(volume int) (*domain.VolumeSummary, error) {
|
||||
var sum domain.VolumeSummary
|
||||
if err := s.readJSON(fmt.Sprintf("summaries/vol-v%02d.json", volume), &sum); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &sum, nil
|
||||
}
|
||||
|
||||
// LoadAllVolumeSummaries 加载所有已有卷摘要。
|
||||
// 从分层大纲获取实际卷数,无分层大纲时扫描到首个缺失为止。
|
||||
func (s *Store) LoadAllVolumeSummaries() ([]domain.VolumeSummary, error) {
|
||||
maxVol := s.volumeCount()
|
||||
var result []domain.VolumeSummary
|
||||
for vol := 1; vol <= maxVol; vol++ {
|
||||
sum, err := s.LoadVolumeSummary(vol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sum != nil {
|
||||
result = append(result, *sum)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// volumeCount 从分层大纲获取卷数,无大纲时返回安全上限。
|
||||
func (s *Store) volumeCount() int {
|
||||
volumes, err := s.LoadLayeredOutline()
|
||||
if err == nil && len(volumes) > 0 {
|
||||
return len(volumes)
|
||||
}
|
||||
return 20
|
||||
}
|
||||
|
||||
// arcCountForVolume 从分层大纲获取指定卷的弧数,无大纲时返回安全上限。
|
||||
func (s *Store) arcCountForVolume(volume int) int {
|
||||
volumes, err := s.LoadLayeredOutline()
|
||||
if err == nil {
|
||||
for _, v := range volumes {
|
||||
if v.Index == volume {
|
||||
return len(v.Arcs)
|
||||
}
|
||||
}
|
||||
}
|
||||
return 20
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user