Files
backend/internal/service/document_service/snap_shot.go
T
2026-07-15 22:42:31 +08:00

105 lines
3.8 KiB
Go

package document_service
import (
"context"
"errors"
"github.com/XingfenD/yoresee_doc/internal/model"
"github.com/XingfenD/yoresee_doc/internal/status"
"github.com/XingfenD/yoresee_doc/internal/utils"
"github.com/XingfenD/yoresee_doc/pkg/cache"
"github.com/XingfenD/yoresee_doc/pkg/key"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
func (s *DocumentService) SaveDocumentYjsSnapshot(ctx context.Context, docExternalID string, state []byte) error {
if len(state) == 0 {
return status.StatusParamError
}
docID, err := s.documentRepo.GetIDByExternalID(docExternalID).Exec(ctx)
if err != nil {
return status.StatusDocumentNotFound
}
if err := s.snapshotRepo.Save(docID, state).Exec(); err != nil {
logrus.Errorf("[Service layer: DocumentService] SaveDocumentYjsSnapshot failed, doc_external_id=%s, doc_id=%d, err=%+v", docExternalID, docID, err)
return status.GenErrWithCustomMsg(status.StatusWriteDBError, "save document snapshot failed")
}
return nil
}
func (s *DocumentService) SaveDocumentSnapshotAndContent(ctx context.Context, docExternalID string, state []byte, content string) (bool, error) {
if len(state) == 0 {
return false, status.StatusParamError
}
contentChanged := false
cacheKey := key.KeyModelByExternalID(key.KeyObjectTypeEnum_Doc, docExternalID)
err := cache.DoubleDelete(
context.Background(),
func() error {
return utils.WithTransaction(s.db, func(tx *gorm.DB) error {
docModel, err := s.documentRepo.GetByExternalID(docExternalID).WithTx(tx).Exec(ctx)
if err != nil {
return status.StatusDocumentNotFound
}
if err := s.snapshotRepo.Save(docModel.ID, state).WithTx(tx).Exec(); err != nil {
logrus.Errorf("[Service layer: DocumentService] SaveDocumentSnapshotAndContent save snapshot failed, doc_external_id=%s, doc_id=%d, err=%+v", docExternalID, docModel.ID, err)
return status.GenErrWithCustomMsg(status.StatusWriteDBError, "save document snapshot failed")
}
if docModel.Content == content {
return nil
}
versionModel := &model.DocumentVersion{
DocumentID: docModel.ID,
Title: docModel.Title,
Content: docModel.Content,
UserID: docModel.UserID,
ChangeSummary: "Sync collab snapshot",
}
if err := s.docVersionRepo.Create(versionModel).WithTx(tx).Exec(); err != nil {
logrus.Errorf("[Service layer: DocumentService] SaveDocumentSnapshotAndContent create version failed, doc_external_id=%s, doc_id=%d, err=%+v", docExternalID, docModel.ID, err)
return status.GenErrWithCustomMsg(status.StatusWriteDBError, "create document version failed")
}
nextDoc := &model.Document{
ID: docModel.ID,
Content: content,
}
if err := s.documentRepo.Update(nextDoc).WithTx(tx).UpdateContent().Exec(); err != nil {
logrus.Errorf("[Service layer: DocumentService] SaveDocumentSnapshotAndContent update content failed, doc_external_id=%s, doc_id=%d, err=%+v", docExternalID, docModel.ID, err)
return status.GenErrWithCustomMsg(status.StatusWriteDBError, "update document content failed")
}
contentChanged = true
return nil
})
},
cacheKey,
)
if err != nil {
return false, err
}
return contentChanged, nil
}
func (s *DocumentService) GetDocumentYjsSnapshot(ctx context.Context, docExternalID string) ([]byte, error) {
docID, err := s.documentRepo.GetIDByExternalID(docExternalID).Exec(ctx)
if err != nil {
return nil, status.StatusDocumentNotFound
}
snapshot, err := s.snapshotRepo.GetByDocID(docID).Exec()
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
logrus.Errorf("[Service layer: DocumentService] GetDocumentYjsSnapshot failed, doc_external_id=%s, doc_id=%d, err=%+v", docExternalID, docID, err)
return nil, status.GenErrWithCustomMsg(status.StatusReadDBError, "get document snapshot failed")
}
return snapshot.YjsState, nil
}