Advertisement
bruimafia

document service

Mar 27th, 2025
301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 7.89 KB | None | 0 0
  1. package services
  2.  
  3. import (
  4.     "document-flow-server/internal/apperrors"
  5.     "document-flow-server/internal/constants"
  6.     "document-flow-server/internal/models"
  7.     "document-flow-server/internal/repositories"
  8.     "document-flow-server/internal/storage"
  9.     "document-flow-server/internal/utils"
  10.     "encoding/json"
  11.     "fmt"
  12.     "github.com/nguyenthenguyen/docx"
  13.     "os"
  14.     "path/filepath"
  15.     "strings"
  16. )
  17.  
  18. // GetDocuments получает список документов с пагинацией
  19. func GetDocuments(page, limit int, user *models.User) (models.DocumentsResponse, error) {
  20.     if !user.HasRole("admin") {
  21.         return repositories.GetUserDocuments(page, limit, user.ID)
  22.     }
  23.     return repositories.GetAllDocuments(page, limit)
  24. }
  25.  
  26. // CreateDocument создаёт новый документ и возвращает его с предзагруженными данными
  27. func CreateDocument(fieldsJSON string, templateFilePath string) (*models.Document, error) {
  28.     var document models.Document
  29.     err := json.Unmarshal([]byte(fieldsJSON), &document)
  30.     if err != nil {
  31.         return nil, fmt.Errorf("недопустимый формат JSON в полях: %w", err)
  32.     }
  33.     document.Creator = nil
  34.     document.Template = nil
  35.  
  36.     // проверка на существование документа с таким же именем у одного и того же пользователя
  37.     exists, err := repositories.DocumentExistsByName(document.Name, document.CreatorID)
  38.     if err != nil {
  39.         return nil, fmt.Errorf("ошибка при проверке существования документа: %w", err)
  40.     }
  41.     if exists {
  42.         return nil, apperrors.ErrDocumentAlreadyExists
  43.     }
  44.  
  45.     updatedFilePath, savedName, err := processDocumentFile(templateFilePath, &document)
  46.     if err != nil {
  47.         return nil, err
  48.     }
  49.     document.FileName = savedName
  50.     document.Path = updatedFilePath
  51.  
  52.     createdDocument, err := repositories.CreateDocument(&document)
  53.     if err != nil {
  54.         return nil, fmt.Errorf("ошибка при сохранении документа в базу данных: %w", err)
  55.     }
  56.  
  57.     user, err := GetUserById(document.CreatorID)
  58.     if err != nil {
  59.         return nil, fmt.Errorf("не удалось получить пользователя: %w", err)
  60.     }
  61.  
  62.     template, err := GetTemplateById(document.TemplateID)
  63.     if err != nil {
  64.         return nil, fmt.Errorf("не удалось получить шаблон: %w", err)
  65.     }
  66.  
  67.     fileNameJson := utils.ToSnakeCase(document.Name) + ".json"
  68.     savePath := filepath.Join(constants.DOCUMENTS_FOLDER, user.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(createdDocument.Name))
  69.  
  70.     documentJSON, err := json.MarshalIndent(document, "", "  ")
  71.     if err != nil {
  72.         return nil, fmt.Errorf("не удалось сериализовать документ в JSON: %v", err)
  73.     }
  74.  
  75.     _, err = storage.SaveFileFromBytes(documentJSON, fileNameJson, savePath)
  76.     if err != nil {
  77.         return nil, fmt.Errorf("не удалось сохранить файл JSON: %v", err)
  78.     }
  79.  
  80.     return createdDocument, nil
  81. }
  82.  
  83. // GetDocumentById получает документ по его идентификатору
  84. func GetDocumentById(id uint64, user *models.User) (*models.Document, error) {
  85.     document, err := repositories.GetDocumentById(id)
  86.     if err != nil {
  87.         fmt.Printf("Документ с ID %d не найден", id)
  88.         return nil, err
  89.     }
  90.  
  91.     if user.ID != document.CreatorID && !user.HasRole("admin") {
  92.         return nil, apperrors.ErrForbidden
  93.     }
  94.  
  95.     return document, nil
  96. }
  97.  
  98. // UpdateDocumentById обновляет документ по его идентификатору
  99. func UpdateDocumentById(id uint64, fieldsJSON string, templateFilePath string, user *models.User) (*models.Document, error) {
  100.     var document models.Document
  101.     err := json.Unmarshal([]byte(fieldsJSON), &document)
  102.     if err != nil {
  103.         return nil, fmt.Errorf("недопустимый формат JSON в полях: %w", err)
  104.     }
  105.     document.Creator = nil
  106.     document.Template = nil
  107.  
  108.     if user.ID != document.CreatorID && !user.HasRole("admin") {
  109.         return nil, apperrors.ErrForbidden
  110.     }
  111.  
  112.     updatedFilePath, savedName, err := processDocumentFile(templateFilePath, &document)
  113.     if err != nil {
  114.         return nil, err
  115.     }
  116.     document.FileName = savedName
  117.     document.Path = updatedFilePath
  118.  
  119.     updatedDocument, err := repositories.UpdateDocumentById(id, &document)
  120.  
  121.     documentJson, err := json.MarshalIndent(updatedDocument, "", "  ")
  122.     if err != nil {
  123.         return nil, fmt.Errorf("не удалось сериализовать документ в JSON: %v", err)
  124.     }
  125.  
  126.     usr, _ := GetUserById(updatedDocument.CreatorID)
  127.     template, _ := GetTemplateById(updatedDocument.TemplateID)
  128.  
  129.     fileNameJson := strings.TrimSuffix(updatedDocument.FileName, filepath.Ext(updatedDocument.FileName)) + ".json"
  130.     _, err = storage.SaveFileFromBytes(documentJson, fileNameJson, filepath.Join(constants.DOCUMENTS_FOLDER, usr.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(updatedDocument.Name)))
  131.     if err != nil {
  132.         return nil, fmt.Errorf("не удалось сохранить файл JSON: %v", err)
  133.     }
  134.  
  135.     return updatedDocument, nil
  136. }
  137.  
  138. // DeleteDocumentById удаляет документ по его идентификатору
  139. func DeleteDocumentById(id uint64, user *models.User) error {
  140.     // получение данных документа перед удалением (чтобы удалить файлы)
  141.     document, err := repositories.GetDocumentById(id)
  142.     if err != nil {
  143.         fmt.Printf("Документ с ID %d не найден", id)
  144.         return err
  145.     }
  146.  
  147.     if user.ID != document.CreatorID && !user.HasRole("admin") {
  148.         return apperrors.ErrForbidden
  149.     }
  150.  
  151.     if err := repositories.DeleteDocumentById(id); err != nil {
  152.         return fmt.Errorf("ошибка при удалении документа из базы данных: %w", err)
  153.     }
  154.  
  155.     // удаление директории документа с сервера
  156.     usr := document.Creator
  157.     template := document.Template
  158.     dirPath := filepath.Join(constants.DOCUMENTS_FOLDER, usr.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(document.Name))
  159.  
  160.     err = storage.DeleteDir(dirPath, 2)
  161.     if err != nil {
  162.         fmt.Printf("Ошибка при удалении директории документа %s\n", err.Error())
  163.     }
  164.  
  165.     return nil
  166. }
  167.  
  168. // SearchDocuments выполняет универсальный поиск по заданному запросу по выбранным полям
  169. func SearchDocuments(query string, page int, limit int, user *models.User) (models.DocumentsResponse, error) {
  170.     if !user.HasRole("admin") {
  171.         return repositories.SearchUserDocuments(query, page, limit, user.ID)
  172.     }
  173.     return repositories.SearchDocuments(query, page, limit)
  174. }
  175.  
  176. func processDocumentFile(templateFilePath string, document *models.Document) (string, string, error) {
  177.     doc, err := docx.ReadDocxFile(templateFilePath)
  178.     if err != nil {
  179.         return "", "", fmt.Errorf("ошибка при открытии документа: %w", err)
  180.     }
  181.  
  182.     editable := doc.Editable()
  183.     fullText := editable.GetContent()
  184.     updatedText := replacePlaceholders(fullText, document.Substitutions)
  185.     editable.SetContent(updatedText)
  186.  
  187.     savedName := utils.ToSnakeCase(document.Name) + ".docx"
  188.     user, err := GetUserById(document.CreatorID)
  189.     template, err := GetTemplateById(document.TemplateID)
  190.  
  191.     if err != nil {
  192.         return "", "", err
  193.     }
  194.     updatedFilePath := filepath.Join(constants.DOCUMENTS_FOLDER, user.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(document.Name), savedName)
  195.  
  196.     dir := filepath.Dir(updatedFilePath)
  197.     if err = os.MkdirAll(dir, os.ModePerm); err != nil {
  198.         return "", "", fmt.Errorf("ошибка при создании директории: %v", err)
  199.     }
  200.  
  201.     err = editable.WriteToFile(updatedFilePath)
  202.     if err != nil {
  203.         return "", "", fmt.Errorf("ошибка при сохранении измененного документа: %v", err)
  204.     }
  205.  
  206.     return updatedFilePath, savedName, nil
  207. }
  208.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement