package main import ( "database/sql" "encoding/json" "fmt" "log" "net/http" "strconv" "github.com/gorilla/mux" _ "github.com/mattn/go-sqlite3" "github.com/rs/cors" ) type Review struct { ID int `json:"id"` ProductID int `json:"product_id"` Username string `json:"username"` Rating int `json:"rating"` Comment string `json:"comment"` CreatedAt string `json:"createdAt"` } var db *sql.DB func main() { var err error db, err = sql.Open("sqlite3", "./reviews.db") if err != nil { log.Fatal("Ошибка открытия БД:", err) } createTable() r := mux.NewRouter() r.HandleFunc("/product/{product_id:[0-9]+}", getReviews).Methods("GET") r.HandleFunc("/product/{product_id:[0-9]+}", addReview).Methods("POST") corsHandler := cors.New(cors.Options{ AllowedOrigins: []string{"http://localhost:3000"}, AllowedMethods: []string{"GET", "POST"}, AllowedHeaders: []string{"Content-Type", "Authorization"}, AllowCredentials: true, }).Handler(r) log.Println("Server is running on port 8080...") if err := http.ListenAndServe(":8080", corsHandler); err != nil { log.Fatal("Ошибка запуска сервера:", err) } } func createTable() { _, err := db.Exec(` CREATE TABLE IF NOT EXISTS reviews ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_id INTEGER NOT NULL, username TEXT NOT NULL, rating INTEGER NOT NULL CHECK(rating >= 1 AND rating <= 5), comment TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `) if err != nil { log.Fatal("Ошибка создания таблицы:", err) } } func getReviews(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) productID := vars["product_id"] rows, err := db.Query("SELECT id, product_id, username, rating, comment, created_at FROM reviews WHERE product_id = ?", productID) if err != nil { http.Error(w, "Ошибка при получении отзывов", http.StatusInternalServerError) log.Println("Ошибка при запросе отзывов:", err) return } defer rows.Close() var reviews []Review for rows.Next() { var review Review if err := rows.Scan(&review.ID, &review.ProductID, &review.Username, &review.Rating, &review.Comment, &review.CreatedAt); err != nil { http.Error(w, "Ошибка при обработке данных", http.StatusInternalServerError) log.Println("Ошибка при сканировании строк:", err) return } reviews = append(reviews, review) } // Log the reviews being returned log.Printf("Reviews fetched: %+v", reviews) if len(reviews) == 0 { http.Error(w, "Нет отзывов", http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(reviews) } func addReview(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) productID, err := strconv.Atoi(vars["product_id"]) if err != nil { http.Error(w, "Некорректный product_id", http.StatusBadRequest) log.Println("Ошибка преобразования product_id:", err) return } var review Review if err := json.NewDecoder(r.Body).Decode(&review); err != nil { http.Error(w, "Некорректный JSON", http.StatusBadRequest) log.Println("Ошибка декодирования JSON:", err) return } review.ProductID = productID log.Printf("Попытка добавить отзыв: %+v", review) stmt, err := db.Prepare("INSERT INTO reviews (product_id, username, rating, comment, created_at) VALUES (?, ?, ?, ?, datetime('now'))") if err != nil { http.Error(w, "Ошибка при подготовке SQL-запроса", http.StatusInternalServerError) log.Println("Ошибка при подготовке запроса:", err) return } defer stmt.Close() result, err := stmt.Exec(review.ProductID, review.Username, review.Rating, review.Comment) if err != nil { http.Error(w, "Ошибка при добавлении отзыва", http.StatusInternalServerError) log.Println("Ошибка при выполнении SQL-запроса:", err) return } rowsAffected, _ := result.RowsAffected() log.Println("Добавлено строк:", rowsAffected) w.WriteHeader(http.StatusCreated) fmt.Fprintln(w, "Отзыв успешно добавлен") }