Advertisement
bruimafia

new doc

Mar 27th, 2025
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 6.08 KB | None | 0 0
  1. // UpdateDocument обновляет существующий документ по идентификатору, заменяя файл и метаданные
  2. //
  3. // @Summary Обновление существующего документа по идентификатору
  4. // @Description Обновляет существующий документ по идентификатору, принимая JSON-метаданные и файл.
  5. // @Tags Документы
  6. // @Accept multipart/form-data
  7. // @Produce json
  8. // @Param id path int true "ID документа"
  9. // @Param document formData string false "Обновленные метаданные документа в формате JSON типа Document"
  10. // @Success 200 {object} models.Document "Обновленный документ"
  11. // @Failure 400 "Ошибка запроса (неверные данные формы, некорректный ID или отсутствие данных)"
  12. // @Failure 403 "Доступ запрещен"
  13. // @Failure 500 "Внутренняя ошибка сервера"
  14. // @Router /documents/{id} [patch]
  15. func UpdateDocument(w http.ResponseWriter, r *http.Request) {
  16.     holder := utils.GetRequestValuesHolder(r, "id", "document", "templateFilePath")
  17.  
  18.     id, err := holder.Uint64FromPath("id").Get()
  19.     utils.ThrowIfNotNil(w, err)
  20.  
  21.     documentJsonPtr := holder.StringFromData("document").Get()
  22.     var documentJson string
  23.     if documentJsonPtr != nil {
  24.         documentJson = *documentJsonPtr
  25.     }
  26.  
  27.     user, _ := auth.GetUserFromContext(r)
  28.     updatedDocument, err := services.UpdateDocumentById(*id, documentJson, user)
  29.     utils.ThrowIfNotNil(w, err)
  30.  
  31.     utils.WriteJSONResponse(w, updatedDocument, http.StatusOK)
  32. }
  33.  
  34. // сервис
  35. // UpdateDocumentById обновляет документ по его идентификатору
  36. func UpdateDocumentById(id uint64, fieldsJSON string, user *models.User) (*models.Document, error) {
  37.     currentDocument, err := repositories.GetDocumentById(id)
  38.     if err != nil {
  39.         return nil, err
  40.     }
  41.  
  42.     updates := make(map[string]interface{})
  43.     if fieldsJSON != "" {
  44.         if err := json.Unmarshal([]byte(fieldsJSON), &updates); err != nil {
  45.             return nil, fmt.Errorf("неверный формат JSON: %v", err)
  46.         }
  47.  
  48.         if subs, ok := updates["substitutions"].(map[string]interface{}); ok {
  49.             subsMap := make(models.SubstitutionsMap)
  50.             for k, v := range subs {
  51.                 if s, ok := v.(string); ok {
  52.                     subsMap[k] = s
  53.                 }
  54.             }
  55.             updates["substitutions"] = subsMap
  56.         }
  57.     }
  58.  
  59.     var newName string
  60.     var nameUpdated bool
  61.     if nameValue, ok := updates["name"]; ok {
  62.         newNameStr, okName := nameValue.(string)
  63.         if !okName {
  64.             return nil, fmt.Errorf("поле 'name' должно быть строкой")
  65.         }
  66.         newName = newNameStr
  67.         nameUpdated = true
  68.     } else {
  69.         newName = currentDocument.Name
  70.         nameUpdated = false
  71.     }
  72.  
  73.     if nameUpdated && newName != currentDocument.Name {
  74.         exists, err := repositories.DocumentExistsByName(newName, currentDocument.CreatorID)
  75.         if err != nil {
  76.             return nil, fmt.Errorf("ошибка проверки имени: %v", err)
  77.         }
  78.         if exists {
  79.             return nil, apperrors.ErrDocumentAlreadyExists
  80.         }
  81.     }
  82.  
  83.     for key, value := range updates {
  84.         switch key {
  85.         case "name":
  86.             if name, ok := value.(string); ok {
  87.                 currentDocument.Name = name
  88.             }
  89.         case "substitutions":
  90.             if subs, ok := value.(models.SubstitutionsMap); ok {
  91.                 currentDocument.Substitutions = subs
  92.             }
  93.         }
  94.     }
  95.  
  96.     updatedFilePath, savedName, err := processDocumentFile(currentDocument.Template.Path, currentDocument)
  97.     if err != nil {
  98.         return nil, err
  99.     }
  100.     currentDocument.FileName = savedName
  101.     currentDocument.Path = updatedFilePath
  102.     updates["path"] = updatedFilePath
  103.     updates["file_name"] = savedName
  104.  
  105.     allowedFields := map[string]bool{"name": true, "substitutions": true, "path": true, "file_name": true}
  106.     filteredUpdates := make(map[string]interface{})
  107.     for key, val := range updates {
  108.         if allowedFields[key] {
  109.             filteredUpdates[key] = val
  110.         }
  111.     }
  112.  
  113.     // если есть что обновлять в БД
  114.     var updatedDocument *models.Document
  115.     if len(filteredUpdates) > 0 || nameUpdated {
  116.         updatedDocument, err = repositories.UpdateDocumentById(id, filteredUpdates)
  117.         if err != nil {
  118.             return nil, err
  119.         }
  120.     } else {
  121.         return currentDocument, nil
  122.     }
  123.  
  124.     documentJson, err := json.MarshalIndent(updatedDocument, "", "  ")
  125.     if err != nil {
  126.         return nil, fmt.Errorf("не удалось сериализовать документ в JSON: %v", err)
  127.     }
  128.  
  129.     usr, _ := GetUserById(updatedDocument.CreatorID)
  130.     template, _ := GetTemplateById(updatedDocument.TemplateID)
  131.  
  132.     fileNameJson := strings.TrimSuffix(updatedDocument.FileName, filepath.Ext(updatedDocument.FileName)) + ".json"
  133.     _, err = storage.SaveFileFromBytes(documentJson, fileNameJson, filepath.Join(constants.DOCUMENTS_FOLDER, usr.Info.GetFullName(), utils.ToSnakeCase(template.Name), utils.ToSnakeCase(updatedDocument.Name)))
  134.     if err != nil {
  135.         return nil, fmt.Errorf("не удалось сохранить файл JSON: %v", err)
  136.     }
  137.  
  138.     return updatedDocument, nil
  139. }
  140.  
  141. // репозиторий
  142. // UpdateDocumentById обновляет документ по его идентификатору
  143. func UpdateDocumentById(id uint64, updates map[string]interface{}) (*models.Document, error) {
  144.     var document models.Document
  145.  
  146.     // преобразование markers к SubstitutionsMap
  147.     if subs, ok := updates["substitutions"].(map[string]interface{}); ok {
  148.         subsMap := make(models.SubstitutionsMap)
  149.         for k, v := range subs {
  150.             if s, ok := v.(string); ok {
  151.                 subsMap[k] = s
  152.             }
  153.         }
  154.         updates["substitutions"] = subsMap
  155.     }
  156.  
  157.     err := database.OpenWriteTransaction(func(tx *gorm.DB) error {
  158.         result := tx.Model(&models.Document{}).Where("id = ?", id).Updates(updates)
  159.         if result.Error != nil {
  160.             return result.Error
  161.         }
  162.         if result.RowsAffected == 0 {
  163.             return apperrors.ErrDocumentNotFound
  164.         }
  165.  
  166.         if err := tx.Scopes(scopes.PreloadCreator).First(&document, id).Error; err != nil {
  167.             return err
  168.         }
  169.  
  170.         document.Creator.DepartmentUserToDepartmentWithTitle()
  171.         return nil
  172.     })
  173.  
  174.     return &document, err
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement