Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // UpdateDocument обновляет существующий документ по идентификатору, заменяя файл и метаданные
- //
- // @Summary Обновление существующего документа по идентификатору
- // @Description Обновляет существующий документ по идентификатору, принимая JSON-метаданные и файл.
- // @Tags Документы
- // @Accept multipart/form-data
- // @Produce json
- // @Param id path int true "ID документа"
- // @Param document formData string false "Обновленные метаданные документа в формате JSON типа Document"
- // @Success 200 {object} models.Document "Обновленный документ"
- // @Failure 400 "Ошибка запроса (неверные данные формы, некорректный ID или отсутствие данных)"
- // @Failure 403 "Доступ запрещен"
- // @Failure 500 "Внутренняя ошибка сервера"
- // @Router /documents/{id} [patch]
- func UpdateDocument(w http.ResponseWriter, r *http.Request) {
- holder := utils.GetRequestValuesHolder(r, "id", "document", "templateFilePath")
- id, err := holder.Uint64FromPath("id").Get()
- utils.ThrowIfNotNil(w, err)
- documentJsonPtr := holder.StringFromData("document").Get()
- var documentJson string
- if documentJsonPtr != nil {
- documentJson = *documentJsonPtr
- }
- user, _ := auth.GetUserFromContext(r)
- updatedDocument, err := services.UpdateDocumentById(*id, documentJson, user)
- utils.ThrowIfNotNil(w, err)
- utils.WriteJSONResponse(w, updatedDocument, http.StatusOK)
- }
- // сервис
- // UpdateDocumentById обновляет документ по его идентификатору
- func UpdateDocumentById(id uint64, fieldsJSON string, user *models.User) (*models.Document, error) {
- currentDocument, err := repositories.GetDocumentById(id)
- if err != nil {
- return nil, err
- }
- updates := make(map[string]interface{})
- if fieldsJSON != "" {
- if err := json.Unmarshal([]byte(fieldsJSON), &updates); err != nil {
- return nil, fmt.Errorf("неверный формат JSON: %v", err)
- }
- if subs, ok := updates["substitutions"].(map[string]interface{}); ok {
- subsMap := make(models.SubstitutionsMap)
- for k, v := range subs {
- if s, ok := v.(string); ok {
- subsMap[k] = s
- }
- }
- updates["substitutions"] = subsMap
- }
- }
- var newName string
- var nameUpdated bool
- if nameValue, ok := updates["name"]; ok {
- newNameStr, okName := nameValue.(string)
- if !okName {
- return nil, fmt.Errorf("поле 'name' должно быть строкой")
- }
- newName = newNameStr
- nameUpdated = true
- } else {
- newName = currentDocument.Name
- nameUpdated = false
- }
- if nameUpdated && newName != currentDocument.Name {
- exists, err := repositories.DocumentExistsByName(newName, currentDocument.CreatorID)
- if err != nil {
- return nil, fmt.Errorf("ошибка проверки имени: %v", err)
- }
- if exists {
- return nil, apperrors.ErrDocumentAlreadyExists
- }
- }
- for key, value := range updates {
- switch key {
- case "name":
- if name, ok := value.(string); ok {
- currentDocument.Name = name
- }
- case "substitutions":
- if subs, ok := value.(models.SubstitutionsMap); ok {
- currentDocument.Substitutions = subs
- }
- }
- }
- updatedFilePath, savedName, err := processDocumentFile(currentDocument.Template.Path, currentDocument)
- if err != nil {
- return nil, err
- }
- currentDocument.FileName = savedName
- currentDocument.Path = updatedFilePath
- updates["path"] = updatedFilePath
- updates["file_name"] = savedName
- allowedFields := map[string]bool{"name": true, "substitutions": true, "path": true, "file_name": true}
- filteredUpdates := make(map[string]interface{})
- for key, val := range updates {
- if allowedFields[key] {
- filteredUpdates[key] = val
- }
- }
- // если есть что обновлять в БД
- var updatedDocument *models.Document
- if len(filteredUpdates) > 0 || nameUpdated {
- updatedDocument, err = repositories.UpdateDocumentById(id, filteredUpdates)
- if err != nil {
- return nil, err
- }
- } else {
- return currentDocument, nil
- }
- 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
- }
- // репозиторий
- // UpdateDocumentById обновляет документ по его идентификатору
- func UpdateDocumentById(id uint64, updates map[string]interface{}) (*models.Document, error) {
- var document models.Document
- // преобразование markers к SubstitutionsMap
- if subs, ok := updates["substitutions"].(map[string]interface{}); ok {
- subsMap := make(models.SubstitutionsMap)
- for k, v := range subs {
- if s, ok := v.(string); ok {
- subsMap[k] = s
- }
- }
- updates["substitutions"] = subsMap
- }
- err := database.OpenWriteTransaction(func(tx *gorm.DB) error {
- result := tx.Model(&models.Document{}).Where("id = ?", id).Updates(updates)
- if result.Error != nil {
- return result.Error
- }
- if result.RowsAffected == 0 {
- return apperrors.ErrDocumentNotFound
- }
- if err := tx.Scopes(scopes.PreloadCreator).First(&document, id).Error; err != nil {
- return err
- }
- document.Creator.DepartmentUserToDepartmentWithTitle()
- return nil
- })
- return &document, err
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement