package handlers import ( "bytes" "encoding/json" "io" "log" "mime/multipart" "net/http" "pocketbaseSigner/config" "pocketbaseSigner/models" ) func UploadHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed) return } // Получаем токен из cookie cookie, err := r.Cookie("pb_auth") if err != nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } // Получаем ID пользователя из cookie userIdCookie, err := r.Cookie("user_id") if err != nil { log.Printf("Ошибка при получении ID пользователя: %v", err) http.Redirect(w, r, "/login", http.StatusSeeOther) return } // Получаем текущие данные пользователя url := config.PocketBaseURL + "/api/collections/users/records/" + userIdCookie.Value req, err := http.NewRequest("GET", url, nil) if err != nil { log.Printf("Ошибка при создании запроса: %v", err) http.Error(w, "Внутренняя ошибка сервера", http.StatusInternalServerError) return } req.Header.Set("Authorization", cookie.Value) client := &http.Client{} resp, err := client.Do(req) if err != nil { log.Printf("Ошибка при получении данных пользователя: %v", err) http.Error(w, "Ошибка при получении данных", http.StatusInternalServerError) return } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { log.Printf("Ошибка при чтении ответа: %v", err) http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError) return } var userData models.UserData if err := json.Unmarshal(body, &userData); err != nil { log.Printf("Ошибка при разборе JSON: %v", err) http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError) return } // Получаем файл из формы file, header, err := r.FormFile("files") if err != nil { log.Printf("Ошибка при получении файла: %v", err) http.Error(w, "Ошибка при загрузке файла", http.StatusBadRequest) return } defer file.Close() // Создаем multipart writer для отправки файла requestBody := &bytes.Buffer{} writer := multipart.NewWriter(requestBody) // Добавляем файл part, err := writer.CreateFormFile("files", header.Filename) if err != nil { log.Printf("Ошибка при создании формы: %v", err) http.Error(w, "Ошибка при подготовке файла", http.StatusInternalServerError) return } // Копируем содержимое файла _, err = io.Copy(part, file) if err != nil { log.Printf("Ошибка при копировании файла: %v", err) http.Error(w, "Ошибка при обработке файла", http.StatusInternalServerError) return } // Добавляем существующие файлы for _, existingFile := range userData.Files { part, err := writer.CreateFormFile("files", existingFile) if err != nil { log.Printf("Ошибка при добавлении существующего файла: %v", err) continue } // Получаем содержимое существующего файла fileUrl := config.PocketBaseURL + "/api/files/_pb_users_auth_/" + userIdCookie.Value + "/" + existingFile fileReq, err := http.NewRequest("GET", fileUrl, nil) if err != nil { log.Printf("Ошибка при создании запроса для существующего файла: %v", err) continue } fileReq.Header.Set("Authorization", cookie.Value) fileResp, err := client.Do(fileReq) if err != nil { log.Printf("Ошибка при получении существующего файла: %v", err) continue } _, err = io.Copy(part, fileResp.Body) fileResp.Body.Close() if err != nil { log.Printf("Ошибка при копировании существующего файла: %v", err) continue } } // Закрываем writer err = writer.Close() if err != nil { log.Printf("Ошибка при закрытии writer: %v", err) http.Error(w, "Ошибка при подготовке запроса", http.StatusInternalServerError) return } // Создаем запрос к PocketBase url = config.PocketBaseURL + "/api/collections/users/records/" + userIdCookie.Value log.Printf("Отправка запроса на URL: %s", url) log.Printf("Content-Type: %s", writer.FormDataContentType()) req, err = http.NewRequest("PATCH", url, requestBody) if err != nil { log.Printf("Ошибка при создании запроса: %v", err) http.Error(w, "Ошибка при отправке файла", http.StatusInternalServerError) return } // Устанавливаем заголовки req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Authorization", cookie.Value) // Отправляем запрос resp, err = client.Do(req) if err != nil { log.Printf("Ошибка при отправке запроса: %v", err) http.Error(w, "Ошибка при загрузке файла", http.StatusInternalServerError) return } defer resp.Body.Close() // Читаем ответ respBody, _ := io.ReadAll(resp.Body) log.Printf("Ответ сервера (статус %d): %s", resp.StatusCode, string(respBody)) // Проверяем ответ if resp.StatusCode != http.StatusOK { log.Printf("Ошибка при загрузке файла (статус %d): %s", resp.StatusCode, string(respBody)) http.Error(w, "Ошибка при загрузке файла", resp.StatusCode) return } // Перенаправляем обратно на дашборд http.Redirect(w, r, "/dashboard", http.StatusSeeOther) }