Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package services
- import (
- "document-flow-server/internal/apperrors"
- "document-flow-server/internal/constants"
- "document-flow-server/internal/models"
- "document-flow-server/internal/repositories"
- "document-flow-server/internal/storage"
- "document-flow-server/internal/utils"
- "encoding/json"
- "fmt"
- "github.com/nguyenthenguyen/docx"
- "os"
- "path/filepath"
- "strings"
- )
- // GetDocuments получает список документов с пагинацией
- func GetDocuments(page, limit int, user *models.User) (models.DocumentsResponse, error) {
- if !user.HasRole("admin") {
- return repositories.GetUserDocuments(page, limit, user.ID)
- }
- return repositories.GetAllDocuments(page, limit)
- }
- // CreateDocument создаёт новый документ и возвращает его с предзагруженными данными
- func CreateDocument(fieldsJSON string, templateFilePath string) (*models.Document, error) {
- var document models.Document
- err := json.Unmarshal([]byte(fieldsJSON), &document)
- if err != nil {
- return nil, fmt.Errorf("недопустимый формат JSON в полях: %w", err)
- }
- document.Creator = nil
- document.Template = nil
- // проверка на существование документа с таким же именем у одного и того же пользователя
- exists, err := repositories.DocumentExistsByName(document.Name, document.CreatorID)
- if err != nil {
- return nil, fmt.Errorf("ошибка при проверке существования документа: %w", err)
- }
- if exists {
- return nil, apperrors.ErrDocumentAlreadyExists
- }
- updatedFilePath, savedName, err := processDocumentFile(templateFilePath, &document)
- if err != nil {
- return nil, err
- }
- document.FileName = savedName
- document.Path = updatedFilePath
- createdDocument, err := repositories.CreateDocument(&document)
- if err != nil {
- return nil, fmt.Errorf("ошибка при сохранении документа в базу данных: %w", err)
- }
- user, err := GetUserById(document.CreatorID)
- if err != nil {
- return nil, fmt.Errorf("не удалось получить пользователя: %w", err)
- }
- template, err := GetTemplateById(document.TemplateID)
- if err != nil {
- return nil, fmt.Errorf("не удалось получить шаблон: %w", err)
- }
- fileNameJson := utils.ToSnakeCase(document.Name) + ".json"
- savePath := filepath.Join(constants.DOCUMENTS_FOLDER, user.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(createdDocument.Name))
- documentJSON, err := json.MarshalIndent(document, "", " ")
- if err != nil {
- return nil, fmt.Errorf("не удалось сериализовать документ в JSON: %v", err)
- }
- _, err = storage.SaveFileFromBytes(documentJSON, fileNameJson, savePath)
- if err != nil {
- return nil, fmt.Errorf("не удалось сохранить файл JSON: %v", err)
- }
- return createdDocument, nil
- }
- // GetDocumentById получает документ по его идентификатору
- func GetDocumentById(id uint64, user *models.User) (*models.Document, error) {
- document, err := repositories.GetDocumentById(id)
- if err != nil {
- fmt.Printf("Документ с ID %d не найден", id)
- return nil, err
- }
- if user.ID != document.CreatorID && !user.HasRole("admin") {
- return nil, apperrors.ErrForbidden
- }
- return document, nil
- }
- // UpdateDocumentById обновляет документ по его идентификатору
- func UpdateDocumentById(id uint64, fieldsJSON string, templateFilePath string, user *models.User) (*models.Document, error) {
- var document models.Document
- err := json.Unmarshal([]byte(fieldsJSON), &document)
- if err != nil {
- return nil, fmt.Errorf("недопустимый формат JSON в полях: %w", err)
- }
- document.Creator = nil
- document.Template = nil
- if user.ID != document.CreatorID && !user.HasRole("admin") {
- return nil, apperrors.ErrForbidden
- }
- updatedFilePath, savedName, err := processDocumentFile(templateFilePath, &document)
- if err != nil {
- return nil, err
- }
- document.FileName = savedName
- document.Path = updatedFilePath
- updatedDocument, err := repositories.UpdateDocumentById(id, &document)
- documentJson, err := json.MarshalIndent(updatedDocument, "", " ")
- if err != nil {
- return nil, fmt.Errorf("не удалось сериализовать документ в JSON: %v", err)
- }
- usr, _ := GetUserById(updatedDocument.CreatorID)
- template, _ := GetTemplateById(updatedDocument.TemplateID)
- fileNameJson := strings.TrimSuffix(updatedDocument.FileName, filepath.Ext(updatedDocument.FileName)) + ".json"
- _, err = storage.SaveFileFromBytes(documentJson, fileNameJson, filepath.Join(constants.DOCUMENTS_FOLDER, usr.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(updatedDocument.Name)))
- if err != nil {
- return nil, fmt.Errorf("не удалось сохранить файл JSON: %v", err)
- }
- return updatedDocument, nil
- }
- // DeleteDocumentById удаляет документ по его идентификатору
- func DeleteDocumentById(id uint64, user *models.User) error {
- // получение данных документа перед удалением (чтобы удалить файлы)
- document, err := repositories.GetDocumentById(id)
- if err != nil {
- fmt.Printf("Документ с ID %d не найден", id)
- return err
- }
- if user.ID != document.CreatorID && !user.HasRole("admin") {
- return apperrors.ErrForbidden
- }
- if err := repositories.DeleteDocumentById(id); err != nil {
- return fmt.Errorf("ошибка при удалении документа из базы данных: %w", err)
- }
- // удаление директории документа с сервера
- usr := document.Creator
- template := document.Template
- dirPath := filepath.Join(constants.DOCUMENTS_FOLDER, usr.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(document.Name))
- err = storage.DeleteDir(dirPath, 2)
- if err != nil {
- fmt.Printf("Ошибка при удалении директории документа %s\n", err.Error())
- }
- return nil
- }
- // SearchDocuments выполняет универсальный поиск по заданному запросу по выбранным полям
- func SearchDocuments(query string, page int, limit int, user *models.User) (models.DocumentsResponse, error) {
- if !user.HasRole("admin") {
- return repositories.SearchUserDocuments(query, page, limit, user.ID)
- }
- return repositories.SearchDocuments(query, page, limit)
- }
- func processDocumentFile(templateFilePath string, document *models.Document) (string, string, error) {
- doc, err := docx.ReadDocxFile(templateFilePath)
- if err != nil {
- return "", "", fmt.Errorf("ошибка при открытии документа: %w", err)
- }
- editable := doc.Editable()
- fullText := editable.GetContent()
- updatedText := replacePlaceholders(fullText, document.Substitutions)
- editable.SetContent(updatedText)
- savedName := utils.ToSnakeCase(document.Name) + ".docx"
- user, err := GetUserById(document.CreatorID)
- template, err := GetTemplateById(document.TemplateID)
- if err != nil {
- return "", "", err
- }
- updatedFilePath := filepath.Join(constants.DOCUMENTS_FOLDER, user.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(document.Name), savedName)
- dir := filepath.Dir(updatedFilePath)
- if err = os.MkdirAll(dir, os.ModePerm); err != nil {
- return "", "", fmt.Errorf("ошибка при создании директории: %v", err)
- }
- err = editable.WriteToFile(updatedFilePath)
- if err != nil {
- return "", "", fmt.Errorf("ошибка при сохранении измененного документа: %v", err)
- }
- return updatedFilePath, savedName, nil
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement