@@ -139,6 +139,34 @@ func (s *Service) Save(ctx context.Context, version string, req SaveRequest, act
|
||||
return s.Get(saved.Version)
|
||||
}
|
||||
|
||||
func (s *Service) SyncFromLegacyUpdateInfo(ctx context.Context, raw string, actor string) error {
|
||||
if strings.TrimSpace(raw) == "" {
|
||||
return nil
|
||||
}
|
||||
item, parsed, formatted, err := parseNotice([]byte(raw), "", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item.RawJSON = formatted
|
||||
current, err := s.store.GetReleaseNotice(item.Version)
|
||||
if err == nil && current.RawJSON != "" && current.RawJSON != formatted {
|
||||
_, _ = s.store.SaveReleaseNoticeRevision(item.Version, current.RawJSON, "auto backup before legacy update-info sync", actor)
|
||||
}
|
||||
saved, err := s.store.UpsertReleaseNotice(item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = s.store.SaveReleaseNoticeRevision(saved.Version, formatted, "synced from update-info.json", actor)
|
||||
if err := s.writeNoticeFile(saved, formatted); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.writeTotalIndex(saved, parsed); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = s.store.InsertAudit(db.AuditLog{Actor: actor, Type: "release_notice.synced", Target: saved.Version, Message: "版本日志已从兼容 update-info.json 同步"})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) Restore(ctx context.Context, version string, revisionID int64, actor string) (Document, error) {
|
||||
revision, err := s.store.GetReleaseNoticeRevision(version, revisionID)
|
||||
if err != nil {
|
||||
@@ -227,10 +255,7 @@ func (s *Service) writeTotalIndex(item db.ReleaseNotice, parsed map[string]any)
|
||||
|
||||
func (s *Service) syncLegacyUpdateInfo(item db.ReleaseNotice, parsed map[string]any) error {
|
||||
path := filepath.Join(s.cfg.UpdatePublicDir, "update-info.json")
|
||||
payload := map[string]any{}
|
||||
if data, err := os.ReadFile(path); err == nil {
|
||||
_ = json.Unmarshal(data, &payload)
|
||||
}
|
||||
payload := s.legacyUpdateBase(path)
|
||||
payload["app_version"] = item.Version
|
||||
setNonEmpty(payload, "build", item.Build)
|
||||
setNonEmpty(payload, "channel", item.Channel)
|
||||
@@ -256,6 +281,36 @@ func (s *Service) syncLegacyUpdateInfo(item db.ReleaseNotice, parsed map[string]
|
||||
return atomicWrite(path, append(data, '\n'))
|
||||
}
|
||||
|
||||
func (s *Service) legacyUpdateBase(currentPath string) map[string]any {
|
||||
payload := map[string]any{}
|
||||
for _, path := range []string{
|
||||
filepath.Join(s.cfg.LegacyUpdateDir, "public", "update-info.json"),
|
||||
currentPath,
|
||||
} {
|
||||
if data, err := os.ReadFile(path); err == nil {
|
||||
var doc map[string]any
|
||||
if json.Unmarshal(data, &doc) == nil {
|
||||
for key, value := range doc {
|
||||
payload[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if payload["app_version"] == nil {
|
||||
if value, ok := payload["appVersion"]; ok {
|
||||
payload["app_version"] = value
|
||||
} else if value, ok := payload["latestVersion"]; ok {
|
||||
payload["app_version"] = value
|
||||
}
|
||||
}
|
||||
if payload["manifest_version"] == nil {
|
||||
if value, ok := payload["manifestVersion"]; ok {
|
||||
payload["manifest_version"] = value
|
||||
}
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
func parseAndFormat(data []byte, fallbackVersion, noticeFile string) (map[string]any, string, error) {
|
||||
_, parsed, formatted, err := parseNotice(data, fallbackVersion, noticeFile)
|
||||
return parsed, formatted, err
|
||||
@@ -270,7 +325,7 @@ func parseNotice(data []byte, fallbackVersion, noticeFile string) (db.ReleaseNot
|
||||
}
|
||||
version := firstNonEmpty(stringValue(parsed, "app_version"), stringValue(parsed, "version"), fallbackVersion)
|
||||
if version == "" {
|
||||
return db.ReleaseNotice{}, nil, "", errors.New("version or app_version is required")
|
||||
return db.ReleaseNotice{}, nil, "", errors.New("版本日志需要填写 version 或 app_version")
|
||||
}
|
||||
if noticeFile == "" {
|
||||
noticeFile = version + ".json"
|
||||
|
||||
Reference in New Issue
Block a user