package main import ( "bytes" "database/sql" "encoding/json" "fmt" "log" "net/http" "os" "strconv" "strings" "time" "github.com/google/uuid" "github.com/gorilla/handlers" _ "github.com/mattn/go-sqlite3" ) type User struct { ID int `json:"id"` Email string `json:"email"` Password string `json:"password"` } var db *sql.DB func create_table(command string) { _, err := db.Exec(command) if err != nil { log.Fatal("Ошибка при создании таблицы:", err) } fmt.Println("База данных готова к работе.") } func initDB() { var err error dbFile := "UNITED.db" db, err = sql.Open("sqlite3", dbFile) if err != nil { log.Fatal("Ошибка подключения к базе данных:", err) } // Create tables if they don't exist create_table(` CREATE TABLE IF NOT EXISTS pay_urls ( id TEXT PRIMARY KEY, url TEXT NOT NULL );`) create_table(` CREATE TABLE IF NOT EXISTS order_list ( order_id TEXT PRIMARY KEY, total_price REAL NOT NULL, datetime TEXT NOT NULL );`) create_table(`CREATE TABLE IF NOT EXISTS order_lines ( line_id INTEGER PRIMARY KEY AUTOINCREMENT, order_id TEXT NOT NULL, item_id INTEGER NOT NULL, item_title TEXT NOT NULL, item_price REAL NOT NULL, item_quantity INTEGER NOT NULL, FOREIGN KEY (order_id) REFERENCES order_list(order_id) );`) create_table(`CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE, password TEXT NOT NULL );`) fmt.Println("База данных готова к работе.") } /*----------------------------PAYMENT--------------------------------------*/ func payHandler(w http.ResponseWriter, r *http.Request) { // Структура для тела запроса на localhost:5000 type PaymentRequest struct { ID string `json:"id"` Sum float64 `json:"sum"` } // Структура для ответа от localhost:5000 type PaymentResponse struct { Message string `json:"message"` URL string `json:"redir_url"` } cookie, err := r.Cookie("totalPrice") if err != nil { http.Error(w, "Не удалось получить amount из cookies", http.StatusBadRequest) return } // Преобразуем amount из строки в float64 amount, err := strconv.ParseFloat(cookie.Value, 64) if err != nil { http.Error(w, "Некорректное значение amount в cookies", http.StatusBadRequest) return } // Генерируем новый UUID newUUID := uuid.New().String() // Создаем тело запроса для localhost:5000 paymentRequest := PaymentRequest{ ID: newUUID, Sum: amount, } // Преобразуем тело запроса в JSON requestBody, err := json.Marshal(paymentRequest) if err != nil { http.Error(w, "Ошибка при создании запроса", http.StatusInternalServerError) return } // Отправляем POST-запрос на localhost:5000 resp, err := http.Post("http://localhost:5000/pay", "application/json", bytes.NewBuffer(requestBody)) if err != nil { http.Error(w, "Ошибка при отправке запроса на сервер", http.StatusInternalServerError) return } defer resp.Body.Close() // Читаем ответ от сервера var paymentResponse PaymentResponse if err := json.NewDecoder(resp.Body).Decode(&paymentResponse); err != nil { http.Error(w, "Ошибка при чтении ответа от сервера", http.StatusInternalServerError) return } // Сохраняем данные в базу данных insertSQL := `INSERT INTO pay_urls (uuid, url) VALUES (?, ?)` _, err = db.Exec(insertSQL, newUUID, paymentResponse.URL) if err != nil { http.Error(w, "Ошибка при сохранении данных в базу данных", http.StatusInternalServerError) return } // Формируем ответ клиенту в виде простого текста response := fmt.Sprintf("UUID: %s\nURL: %s", newUUID, paymentResponse.URL) // Set uuid cookie cookie = &http.Cookie{ Name: "uuid", Value: newUUID, Expires: time.Now().Add(30 * time.Minute), } http.SetCookie(w, cookie) // Отправляем ответ в виде простого текста w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) w.Write([]byte(response)) } func checkPayHandler(w http.ResponseWriter, r *http.Request) { // Извлекаем uuid из cookie cookie, err := r.Cookie("uuid") if err != nil { http.Error(w, "Не найден cookie с uuid", http.StatusBadRequest) return } uuid := cookie.Value if uuid == "" { http.Error(w, "Пустое значение uuid", http.StatusBadRequest) return } // Проверяем существование uuid в базе данных var exists bool querySQL := `SELECT EXISTS(SELECT 1 FROM pay_urls WHERE uuid = ?)` err = db.QueryRow(querySQL, uuid).Scan(&exists) if err != nil { http.Error(w, "Ошибка при проверке uuid в базе данных", http.StatusInternalServerError) return } if !exists { http.Error(w, "UUID не найден", http.StatusNotFound) return } // Создаем тело запроса для localhost:5000/check_pay checkRequest := struct { UUID string `json:"uuid"` }{ UUID: uuid, } requestBody, err := json.Marshal(checkRequest) if err != nil { http.Error(w, "Ошибка при создании запроса", http.StatusInternalServerError) return } // Отправляем POST-запрос на localhost:5000/check_pay resp, err := http.Post("http://localhost:5000/check_pay", "application/json", bytes.NewBuffer(requestBody)) if err != nil { http.Error(w, "Ошибка при отправке запроса на сервер", http.StatusInternalServerError) return } defer resp.Body.Close() // Читаем ответ от сервера var checkResponse struct { Mes string `json:"mes"` } if err := json.NewDecoder(resp.Body).Decode(&checkResponse); err != nil { http.Error(w, "Ошибка при чтении ответа от сервера", http.StatusInternalServerError) return } // Формируем ответ клиенту в зависимости от полученного результата var response string if checkResponse.Mes == "OK" { response = "OK" } else { response = "GTHO" } // Отправляем ответ в виде простого текста w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) w.Write([]byte(response)) } func add_to_cart(w http.ResponseWriter, r *http.Request) { type CartItem struct { ID int `json:"id"` Title string `json:"title"` Price float64 `json:"price"` Quantity int `json:"quantity"` } type Cart struct { CartItems []CartItem `json:"cart_items"` } cartCookie, err := r.Cookie("cart") if err != nil { http.Error(w, "Cart cookie not found", http.StatusBadRequest) return } fmt.Print("cartCookie.Value: ", cartCookie.Value) cartValue := strings.ReplaceAll(cartCookie.Value, "'", "\"") // Replace single quotes with double quotes var cart Cart err = json.Unmarshal([]byte(cartValue), &cart) if err != nil { http.Error(w, "Invalid cart data format", http.StatusBadRequest) return } for _, item := range cart.CartItems { fmt.Println("Item ID:", item.ID) fmt.Println("Item Title:", item.Title) fmt.Println("Item Price:", item.Price) fmt.Println("Item Quantity:", item.Quantity) } del_cookie, err := r.Cookie("uuid") if err != nil { http.Error(w, "Не найден cookie с uuid", http.StatusBadRequest) return } total_cookie, err := r.Cookie("total_price") if err != nil { http.Error(w, "Не найден cookie с total_price", http.StatusBadRequest) return } total_price := total_cookie.Value order_id := del_cookie.Value fmt.Println("order_id: ", order_id) fmt.Println("total_price: ", total_price) insertSql := `INSERT INTO order_list VALUES (?, ?, ?)` _, err = db.Exec(insertSql, order_id, total_price, time.Now().Format("2006-01-02 15:04:05")) if err != nil { http.Error(w, "Ошибка при сохранении данных в базу данных 1", http.StatusInternalServerError) fmt.Print("Ошибка при сохранении данных в базу данных 1", err) return } for _, item := range cart.CartItems { insertSQL := `INSERT INTO order_lines (order_id, item_id, item_title, item_price, item_quantity) VALUES (?, ?, ?, ?, ?)` _, err = db.Exec(insertSQL, order_id, item.ID, item.Title, item.Price, item.Quantity) if err != nil { http.Error(w, "Ошибка при сохранении данных в базу данных 2", http.StatusInternalServerError) fmt.Println("Ошибка при сохранении данных в базу данных 2", err) return } } // insertSQL := `DELETE FROM url_pays WHERE uuid = ?` // _, err = db.Exec(insertSQL, del_cookie.Value) // if err != nil { // http.Error(w, "Ошибка при сохранении данных в базу данных", http.StatusInternalServerError) // return // } // // Clear uuid cookie // del_cookie = &http.Cookie{ // Name: "uuid", // Value: "", // MaxAge: -1, // } // http.SetCookie(w, del_cookie) // Send success response w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) } /*----------------------------USER-----------------------------------------*/ func registerHandler(w http.ResponseWriter, r *http.Request) { log.Printf("Received request with method: %s", r.Method) if r.Method != http.MethodPost { http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed) return } var user User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, "Ошибка обработки JSON", http.StatusBadRequest) return } if user.Email == "" || user.Password == "" { http.Error(w, "Email и пароль обязательны", http.StatusBadRequest) return } insertQuery := `INSERT INTO users (email, password) VALUES (?, ?)` _, err := db.Exec(insertQuery, user.Email, user.Password) if err != nil { http.Error(w, "Ошибка записи в базу данных", http.StatusInternalServerError) fmt.Println("Ошибка:", err) return } w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]string{"message": "Пользователь успешно зарегистрирован", "email": user.Email}) } func loginHandler(w http.ResponseWriter, r *http.Request) { log.Printf("Received request with method: %s", r.Method) if r.Method != http.MethodPost { http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed) return } var user User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, "Ошибка обработки JSON", http.StatusBadRequest) return } if user.Email == "" || user.Password == "" { http.Error(w, "Email и пароль обязательны", http.StatusBadRequest) return } query := `SELECT id, email, password FROM users WHERE email = ? AND password = ?` var dbUser User err := db.QueryRow(query, user.Email, user.Password).Scan(&dbUser.ID, &dbUser.Email, &dbUser.Password) if err != nil { if err == sql.ErrNoRows { http.Error(w, "Неверные учетные данные", http.StatusUnauthorized) } else { http.Error(w, "Ошибка при проверке учетных данных", http.StatusInternalServerError) } return } w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{"message": "Вход успешен", "email": dbUser.Email}) } func getUsersHandler(w http.ResponseWriter, r *http.Request) { log.Printf("Received request with method: %s", r.Method) if r.Method != http.MethodGet { http.Error(w, "Метод не поддерживается", http.StatusMethodNotAllowed) return } rows, err := db.Query(`SELECT id, email, password FROM users`) if err != nil { http.Error(w, "Ошибка чтения из базы данных", http.StatusInternalServerError) return } defer rows.Close() var users []User for rows.Next() { var user User if err := rows.Scan(&user.ID, &user.Email, &user.Password); err != nil { http.Error(w, "Ошибка обработки данных", http.StatusInternalServerError) return } users = append(users, user) } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(users) } func main() { initDB() defer db.Close() // Setup CORS cors := handlers.CORS( handlers.AllowedOrigins([]string{"*"}), handlers.AllowedMethods([]string{"GET", "POST"}), handlers.AllowedHeaders([]string{"Content-Type"}), ) // Register handlers http.HandleFunc("/api/pay", payHandler) http.HandleFunc("/api/check_pay", checkPayHandler) http.HandleFunc("/api/add_to_cart", add_to_cart) http.HandleFunc("/api/register", registerHandler) http.HandleFunc("/api/login", loginHandler) http.HandleFunc("/api/users", getUsersHandler) // Start server with CORS middleware port := os.Getenv("PORT") if port == "" { port = "8081" } fmt.Println("Go-сервер запущен на порту", port) log.Fatal(http.ListenAndServe(":"+port, cors(http.DefaultServeMux))) }