105 lines
3.8 KiB
Go
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
|
|
}
|