Advertisement
bruimafia

document rep

Mar 27th, 2025
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 9.98 KB | None | 0 0
  1. package repositories
  2.  
  3. import (
  4.     "document-flow-server/internal/apperrors"
  5.     "document-flow-server/internal/database"
  6.     "document-flow-server/internal/models"
  7.     "document-flow-server/internal/repositories/scopes"
  8.     "fmt"
  9.     "strings"
  10.  
  11.     "gorm.io/gorm"
  12. )
  13.  
  14. // GetAllDocuments получает список документов с пагинацией
  15. func GetAllDocuments(page, limit int) (models.DocumentsResponse, error) {
  16.     var documents []models.Document
  17.     var totalCount int64
  18.  
  19.     offset := (page - 1) * limit
  20.  
  21.     err := database.OpenReadTransaction(func(tx *gorm.DB) error {
  22.         if err := tx.Model(&models.Document{}).Count(&totalCount).Error; err != nil {
  23.             return fmt.Errorf("не удалось получить количество документов: %w", err)
  24.         }
  25.  
  26.         if err := tx.Scopes(scopes.PreloadCreator).
  27.             Preload("Template", func(db *gorm.DB) *gorm.DB {
  28.                 return db.Unscoped()
  29.             }).
  30.             Order("updated_at DESC").
  31.             Limit(limit).
  32.             Offset(offset).
  33.             Find(&documents).Error; err != nil {
  34.             return fmt.Errorf("не удалось загрузить документы: %w", err)
  35.         }
  36.  
  37.         for i := range documents {
  38.             documents[i].Creator.DepartmentUserToDepartmentWithTitle()
  39.         }
  40.  
  41.         return nil
  42.     })
  43.  
  44.     if err != nil {
  45.         return models.DocumentsResponse{}, err
  46.     }
  47.  
  48.     return models.DocumentsResponse{
  49.         Documents:  documents,
  50.         TotalCount: totalCount,
  51.         Page:       page,
  52.         Limit:      limit,
  53.     }, nil
  54. }
  55.  
  56. // GetUserDocuments получает список документов с пагинацией конкретного пользователя
  57. func GetUserDocuments(page, limit int, userID uint64) (models.DocumentsResponse, error) {
  58.     var documents []models.Document
  59.     var totalCount int64
  60.  
  61.     offset := (page - 1) * limit
  62.  
  63.     err := database.OpenReadTransaction(func(tx *gorm.DB) error {
  64.         if err := tx.Model(&models.Document{}).
  65.             Where("creator_id = ?", userID).
  66.             Count(&totalCount).Error; err != nil {
  67.             return fmt.Errorf("не удалось получить количество документов: %w", err)
  68.         }
  69.  
  70.         if err := tx.Scopes(scopes.PreloadCreator).
  71.             Preload("Template", func(db *gorm.DB) *gorm.DB {
  72.                 return db.Unscoped()
  73.             }).
  74.             Where("creator_id = ?", userID).
  75.             Order("updated_at DESC").
  76.             Limit(limit).
  77.             Offset(offset).
  78.             Find(&documents).Error; err != nil {
  79.             return fmt.Errorf("не удалось загрузить документы: %w", err)
  80.         }
  81.  
  82.         for i := range documents {
  83.             documents[i].Creator.DepartmentUserToDepartmentWithTitle()
  84.         }
  85.  
  86.         return nil
  87.     })
  88.  
  89.     if err != nil {
  90.         return models.DocumentsResponse{}, err
  91.     }
  92.  
  93.     return models.DocumentsResponse{
  94.         Documents:  documents,
  95.         TotalCount: totalCount,
  96.         Page:       page,
  97.         Limit:      limit,
  98.     }, nil
  99. }
  100.  
  101. // CreateDocument создаёт новый документ и возвращает его с предзагруженными данными
  102. func CreateDocument(document *models.Document) (*models.Document, error) {
  103.     err := database.OpenWriteTransaction(func(tx *gorm.DB) error {
  104.         if err := tx.Create(&document).Error; err != nil {
  105.             return apperrors.ErrDocumentCreationFailed
  106.         }
  107.  
  108.         if err := tx.Scopes(scopes.PreloadCreator).Preload("Template").First(document, document.ID).Error; err != nil {
  109.             return fmt.Errorf("не удалось загрузить созданный документ: %w", err)
  110.         }
  111.  
  112.         document.Creator.DepartmentUserToDepartmentWithTitle()
  113.  
  114.         return nil
  115.     })
  116.  
  117.     if err != nil {
  118.         return nil, err
  119.     }
  120.  
  121.     return document, nil
  122. }
  123.  
  124. // GetDocumentById получает документ по его идентификатору
  125. func GetDocumentById(id uint64) (*models.Document, error) {
  126.     var document models.Document
  127.  
  128.     err := database.OpenReadTransaction(func(tx *gorm.DB) error {
  129.         if err := tx.Scopes(scopes.PreloadCreator).
  130.             Preload("Template", func(db *gorm.DB) *gorm.DB {
  131.                 return db.Unscoped()
  132.             }).
  133.             Where("id = ?", id).
  134.             First(&document).Error; err != nil {
  135.             if err == gorm.ErrRecordNotFound {
  136.                 return apperrors.ErrDocumentNotFound
  137.             }
  138.             return fmt.Errorf("не удалось загрузить документ: %w", err)
  139.         }
  140.  
  141.         document.Creator.DepartmentUserToDepartmentWithTitle()
  142.  
  143.         return nil
  144.     })
  145.  
  146.     if err != nil {
  147.         return nil, err
  148.     }
  149.  
  150.     return &document, nil
  151. }
  152.  
  153. // UpdateDocumentById обновляет документ по его идентификатору
  154. func UpdateDocumentById(id uint64, updateDocument *models.Document) (*models.Document, error) {
  155.     document, err := GetDocumentById(id)
  156.     if err != nil {
  157.         return nil, err
  158.     }
  159.     updateDocument.ID = document.ID
  160.  
  161.     err = database.OpenWriteTransaction(func(tx *gorm.DB) error {
  162.         if err := tx.Where("id = ?", id).Updates(updateDocument).Error; err != nil {
  163.             return apperrors.ErrDocumentUpdateFailed
  164.         }
  165.         return nil
  166.     })
  167.  
  168.     if err != nil {
  169.         return nil, err
  170.     }
  171.  
  172.     return updateDocument, nil
  173. }
  174.  
  175. // DeleteDocumentById удаляет документ по его идентификатору
  176. func DeleteDocumentById(id uint64) error {
  177.     document, err := GetDocumentById(id)
  178.     if err != nil {
  179.         return err
  180.     }
  181.  
  182.     return database.OpenWriteTransaction(func(tx *gorm.DB) error {
  183.  
  184.         if err := tx.Delete(document).Error; err != nil {
  185.             return apperrors.ErrDocumentDeleteFailed
  186.         }
  187.  
  188.         var countSemaTemplateDocument int64
  189.         tx.Model(&models.Document{}).Where("template_id = ?", document.Template.ID).Count(&countSemaTemplateDocument)
  190.  
  191.         return nil
  192.     })
  193. }
  194.  
  195. // SearchDocuments выполняет универсальный поиск по заданному запросу по выбранным полям
  196. func SearchDocuments(query string, page, limit int) (models.DocumentsResponse, error) {
  197.     var documents []models.Document
  198.     var totalCount int64
  199.     var values []interface{}
  200.     var sb strings.Builder
  201.  
  202.     offset := (page - 1) * limit
  203.  
  204.     // поля, в которых ищем информацию
  205.     allowedFields := []string{"name", "substitutions"}
  206.  
  207.     if query != "" {
  208.         for i, column := range allowedFields {
  209.             if i > 0 {
  210.                 sb.WriteString(" OR ")
  211.             }
  212.             if column == "substitutions" {
  213.                 // для поля markers используем jsonb операции для поиска внутри JSON
  214.                 sb.WriteString("substitutions::text ILIKE ?")
  215.                 values = append(values, "%"+query+"%")
  216.             } else {
  217.                 sb.WriteString(column + " ILIKE ?")
  218.                 values = append(values, "%"+query+"%")
  219.             }
  220.         }
  221.     }
  222.  
  223.     querySQL := sb.String()
  224.  
  225.     err := database.OpenReadTransaction(func(tx *gorm.DB) error {
  226.         txWithFilters := tx.Model(&models.Document{})
  227.         if querySQL != "" {
  228.             txWithFilters = txWithFilters.Where(querySQL, values...)
  229.         }
  230.  
  231.         if err := txWithFilters.Count(&totalCount).Error; err != nil {
  232.             return fmt.Errorf("ошибка подсчёта записей: %w", err)
  233.         }
  234.  
  235.         txWithFilters = txWithFilters.Scopes(scopes.PreloadCreator).
  236.             Preload("Template", func(db *gorm.DB) *gorm.DB {
  237.                 return db.Unscoped()
  238.             }).
  239.             Order("updated_at DESC").
  240.             Limit(limit).
  241.             Offset(offset)
  242.         if err := txWithFilters.Find(&documents).Error; err != nil {
  243.             return fmt.Errorf("ошибка загрузки данных: %w", err)
  244.         }
  245.  
  246.         for i := range documents {
  247.             documents[i].Creator.DepartmentUserToDepartmentWithTitle()
  248.         }
  249.  
  250.         return nil
  251.     })
  252.  
  253.     if err != nil {
  254.         return models.DocumentsResponse{}, err
  255.     }
  256.  
  257.     return models.DocumentsResponse{
  258.         Documents:  documents,
  259.         TotalCount: totalCount,
  260.         Page:       page,
  261.         Limit:      limit,
  262.     }, nil
  263. }
  264.  
  265. func SearchUserDocuments(query string, page, limit int, userID uint64) (models.DocumentsResponse, error) {
  266.     var documents []models.Document
  267.     var totalCount int64
  268.     var values []interface{}
  269.     var sb strings.Builder
  270.  
  271.     offset := (page - 1) * limit
  272.  
  273.     // поля, в которых ищем информацию
  274.     allowedFields := []string{"name", "substitutions"}
  275.  
  276.     if query != "" {
  277.         for i, column := range allowedFields {
  278.             if i > 0 {
  279.                 sb.WriteString(" OR ")
  280.             }
  281.             if column == "substitutions" {
  282.                 // для поля markers используем jsonb операции для поиска внутри JSON
  283.                 sb.WriteString("substitutions::text ILIKE ?")
  284.                 values = append(values, "%"+query+"%")
  285.             } else {
  286.                 sb.WriteString(column + " ILIKE ?")
  287.                 values = append(values, "%"+query+"%")
  288.             }
  289.         }
  290.     }
  291.  
  292.     querySQL := sb.String()
  293.  
  294.     err := database.OpenReadTransaction(func(tx *gorm.DB) error {
  295.         txWithFilters := tx.Model(&models.Document{}).Where("creator_id = ?", userID)
  296.         if querySQL != "" {
  297.             txWithFilters = txWithFilters.Where(querySQL, values...)
  298.         }
  299.  
  300.         if err := txWithFilters.Count(&totalCount).Error; err != nil {
  301.             return fmt.Errorf("ошибка подсчёта записей: %w", err)
  302.         }
  303.  
  304.         txWithFilters = txWithFilters.Scopes(scopes.PreloadCreator).
  305.             Preload("Template", func(db *gorm.DB) *gorm.DB {
  306.                 return db.Unscoped()
  307.             }).
  308.             Order("updated_at DESC").
  309.             Limit(limit).
  310.             Offset(offset)
  311.         if err := txWithFilters.Find(&documents).Error; err != nil {
  312.             return fmt.Errorf("ошибка загрузки данных: %w", err)
  313.         }
  314.  
  315.         for i := range documents {
  316.             documents[i].Creator.DepartmentUserToDepartmentWithTitle()
  317.         }
  318.  
  319.         return nil
  320.     })
  321.  
  322.     if err != nil {
  323.         return models.DocumentsResponse{}, err
  324.     }
  325.  
  326.     return models.DocumentsResponse{
  327.         Documents:  documents,
  328.         TotalCount: totalCount,
  329.         Page:       page,
  330.         Limit:      limit,
  331.     }, nil
  332. }
  333.  
  334. // DocumentExistsByName проверяет, существует ли документ с таким именем у того же пользователя
  335. func DocumentExistsByName(name string, creatorID uint64) (bool, error) {
  336.     var count int64
  337.  
  338.     err := database.OpenReadTransaction(func(tx *gorm.DB) error {
  339.         if err := tx.Model(&models.Document{}).
  340.             Where("name = ? AND creator_id = ?", name, creatorID).
  341.             Count(&count).Error; err != nil {
  342.             return fmt.Errorf("ошибка при проверке существования документа: %w", err)
  343.         }
  344.         return nil
  345.     })
  346.  
  347.     if err != nil {
  348.         return false, err
  349.     }
  350.  
  351.     return count > 0, nil
  352. }
  353.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement