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"
- "mime/multipart"
- "os"
- "path/filepath"
- )
- type FileInfo struct {
- OldFilePath string
- OldDirPath string
- NewDirPath string
- NewFileName string
- OldJSONName string
- NewFilePathInOldDir string
- NewFilePath string
- OldJSONInNewPath string
- NewJSONFileName string
- }
- // GetTemplates получает список шаблонов: либо всех, либо с пагинацией
- func GetTemplates(page, limit *int) (models.TemplatesResponse, error) {
- if page == nil || limit == nil {
- return repositories.GetAllTemplates()
- }
- return repositories.GetTemplatesPaginated(*page, *limit)
- }
- // CreateTemplate создаёт новый шаблон и возвращает его с предзагруженными данными
- func CreateTemplate(fieldsJSON string, file *multipart.File, fileHeader *multipart.FileHeader, user *models.User) (*models.Template, error) {
- if !user.HasRole("admin") {
- return nil, apperrors.ErrForbidden
- }
- var template models.Template
- err := json.Unmarshal([]byte(fieldsJSON), &template)
- if err != nil {
- return nil, fmt.Errorf("недопустимый формат JSON в полях: %w", err)
- }
- template.Creator = nil
- // проверка на существование шаблона с таким же именем
- exists, err := repositories.TemplateExistsByName(template.Name)
- if err != nil {
- return nil, fmt.Errorf("ошибка при проверке существования шаблона: %w", err)
- }
- if exists {
- return nil, apperrors.ErrTemplateAlreadyExists
- }
- savedName := utils.ToSnakeCase(template.Name) + filepath.Ext(fileHeader.Filename)
- savedPath, err := storage.SaveFile(*file, savedName, filepath.Join(constants.TEMPLATES_FOLDER, utils.ToSnakeCase(template.Name)))
- if err != nil {
- return nil, err
- }
- template.FileName = savedName
- template.Path = savedPath
- createdTemplate, err := repositories.CreateTemplate(&template)
- if err != nil {
- return nil, fmt.Errorf("ошибка при сохранении шаблона в базу данных: %w", err)
- }
- fileNameJson := utils.ToSnakeCase(template.Name) + ".json"
- savePath := filepath.Join(constants.TEMPLATES_FOLDER, utils.ToSnakeCase(template.Name))
- templateJson, err := json.MarshalIndent(template, "", " ")
- if err != nil {
- return nil, fmt.Errorf("не удалось сериализовать шаблон в JSON: %v", err)
- }
- _, err = storage.SaveFileFromBytes(templateJson, fileNameJson, savePath)
- if err != nil {
- return nil, fmt.Errorf("не удалось сохранить файл JSON: %v", err)
- }
- return createdTemplate, nil
- }
- // GetTemplateById получает шаблон по его идентификатору
- func GetTemplateById(id uint64) (*models.Template, error) {
- return repositories.GetTemplateById(id)
- }
- // UpdateTemplateById обновляет шаблон по его идентификатору
- func UpdateTemplateById(id uint64, fieldsJSON string, file *multipart.File, fileHeader *multipart.FileHeader, user *models.User) (*models.Template, error) {
- if !user.HasRole("admin") {
- return nil, apperrors.ErrForbidden
- }
- currentTemplate, err := repositories.GetTemplateById(id)
- if err != nil {
- return nil, err
- }
- updates := make(map[string]interface{})
- // парсим JSON только если он не пустой
- if fieldsJSON != "" {
- if err := json.Unmarshal([]byte(fieldsJSON), &updates); err != nil {
- return nil, fmt.Errorf("неверный формат JSON: %v", err)
- }
- if markers, ok := updates["markers"].([]interface{}); ok {
- var strArr models.StringArray
- for _, m := range markers {
- if s, ok := m.(string); ok {
- strArr = append(strArr, s)
- }
- }
- updates["markers"] = strArr
- }
- }
- newName, nameUpdated := updates["name"].(string)
- if nameUpdated && newName != currentTemplate.Name {
- exists, err := repositories.TemplateExistsByName(newName)
- if err != nil {
- return nil, fmt.Errorf("ошибка проверки имени: %v", err)
- }
- if exists {
- return nil, apperrors.ErrTemplateAlreadyExists
- }
- } else {
- newName = currentTemplate.Name
- }
- var newDir, newFileName, newFilePath string
- if nameUpdated || file != nil {
- if nameUpdated {
- newDir = utils.ToSnakeCase(newName)
- } else {
- newDir = utils.ToSnakeCase(currentTemplate.Name)
- }
- if file != nil {
- newFileName = utils.ToSnakeCase(newName) + filepath.Ext(fileHeader.Filename)
- } else {
- newFileName = utils.ToSnakeCase(newName) + filepath.Ext(currentTemplate.FileName)
- }
- newFilePath = filepath.Join(constants.TEMPLATES_FOLDER, newDir, newFileName)
- if nameUpdated {
- os.MkdirAll(filepath.Join(constants.TEMPLATES_FOLDER, newDir), os.ModePerm)
- oldDir := filepath.Dir(currentTemplate.Path)
- if file != nil {
- savedPath, err := storage.SaveFile(*file, newFileName, filepath.Join(constants.TEMPLATES_FOLDER, newDir))
- if err != nil {
- return nil, err
- }
- newFilePath = savedPath
- } else {
- os.Rename(currentTemplate.Path, newFilePath)
- oldJsonPath := filepath.Join(oldDir, utils.ToSnakeCase(currentTemplate.Name)+".json")
- newJsonPath := filepath.Join(constants.TEMPLATES_FOLDER, newDir, utils.ToSnakeCase(newName)+".json")
- os.Rename(oldJsonPath, newJsonPath)
- os.Remove(oldDir)
- }
- } else if file != nil {
- savedPath, err := storage.SaveFile(*file, newFileName, filepath.Join(constants.TEMPLATES_FOLDER, newDir))
- if err != nil {
- return nil, err
- }
- newFilePath = savedPath
- }
- updates["path"] = newFilePath
- updates["file_name"] = newFileName
- }
- allowedFields := map[string]bool{"name": true, "description": true, "color": true, "markers": true, "path": true, "file_name": true}
- filteredUpdates := make(map[string]interface{})
- for key, val := range updates {
- if allowedFields[key] {
- filteredUpdates[key] = val
- }
- }
- // если есть что обновлять в БД
- var updatedTemplate *models.Template
- if len(filteredUpdates) > 0 || nameUpdated || file != nil {
- updatedTemplate, err = repositories.UpdateTemplateById(id, filteredUpdates)
- if err != nil {
- return nil, err
- }
- } else {
- return currentTemplate, nil
- }
- jsonData, _ := json.MarshalIndent(updatedTemplate, "", " ")
- jsonFileName := utils.ToSnakeCase(updatedTemplate.Name) + ".json"
- jsonDir := filepath.Join(constants.TEMPLATES_FOLDER, utils.ToSnakeCase(updatedTemplate.Name))
- storage.SaveFileFromBytes(jsonData, jsonFileName, jsonDir)
- return updatedTemplate, nil
- }
- // DeleteTemplateById удаляет шаблон по его идентификатору
- func DeleteTemplateById(id uint64, user *models.User) error {
- if !user.HasRole("admin") {
- return apperrors.ErrForbidden
- }
- // получение данных шаблона перед удалением (чтобы удалить файлы)
- //template, err := repositories.GetTemplateById(id)
- //if err != nil {
- // fmt.Printf("Шаблон с ID %d не найден", id)
- // return err
- //}
- if err := repositories.DeleteTemplateById(id); err != nil {
- return fmt.Errorf("ошибка при удалении шаблона из базы данных: %w", err)
- }
- // удаление директории шаблона с сервера
- // пока временно убрано, чтобы можно было редактировать шаблоны, основанные на удаленных шаблонах
- //dirPath := filepath.Join(constants.TEMPLATES_FOLDER, utils.ToSnakeCase(template.Name))
- //err = storage.DeleteDir(dirPath, 0)
- //if err != nil {
- // fmt.Printf("Ошибка при удалении директории шаблона %s\n", err.Error())
- //}
- return nil
- }
- // SearchTemplates универсально ищет по разным полям
- func SearchTemplates(query string, page, limit *int) (models.TemplatesResponse, error) {
- if page != nil && *page < 1 || limit != nil && *limit < 1 {
- return models.TemplatesResponse{},
- apperrors.ErrInvalidParams.WithCustomMessage("неверные параметры пагинации. page и limit должны быть больше 0")
- }
- return repositories.SearchTemplates(query, *page, *limit)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement