Files
tp/main_dc/yalarba/api_yal/internal/domain/object/handler.go
T
valitovgaziz 979c265e36 On branch main
modified:   main_dc/yalarba/api_yal/internal/domain/account/handler.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/router.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/service.go
	modified:   main_dc/yalarba/api_yal/internal/domain/auth/router.go
	new file:   main_dc/yalarba/api_yal/internal/domain/comment/dto.go
	new file:   main_dc/yalarba/api_yal/internal/domain/feetback/dto.go
	new file:   main_dc/yalarba/api_yal/internal/domain/object/dto.go
	new file:   main_dc/yalarba/api_yal/internal/domain/object/errors.go
	new file:   main_dc/yalarba/api_yal/internal/domain/object/handler.go
	new file:   main_dc/yalarba/api_yal/internal/domain/object/router.go
	new file:   main_dc/yalarba/api_yal/internal/domain/object/service.go
	new file:   main_dc/yalarba/api_yal/internal/domain/object/types.go
	new file:   main_dc/yalarba/api_yal/internal/domain/rating/dto.go
	modified:   main_dc/yalarba/api_yal/internal/models/rating.go
add and not tested Object's domain
2026-03-31 16:53:24 +05:00

296 lines
8.0 KiB
Go

package object
import (
"encoding/json"
"net/http"
"strconv"
"api_yal/internal/middleware"
"github.com/go-chi/chi/v5"
)
type ObjectHandler struct {
objectService ObjectService
}
func NewObjectHandler(objectService ObjectService) *ObjectHandler {
return &ObjectHandler{
objectService: objectService,
}
}
// GetObjectByID обрабатывает GET /objects/{id}
func (h *ObjectHandler) GetObjectByID(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32)
if err != nil {
http.Error(w, "Invalid object ID", http.StatusBadRequest)
return
}
response, err := h.objectService.GetObjectByID(r.Context(), uint(id))
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusOK, response)
}
// CreateObject обрабатывает POST /objects
func (h *ObjectHandler) CreateObject(w http.ResponseWriter, r *http.Request) {
var req CreateObjectRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
// Получаем ID пользователя из контекста (из AuthMiddleware)
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Устанавливаем owner_id из аутентифицированного пользователя
req.OwnerID = userID
response, err := h.objectService.CreateObject(r.Context(), &req)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusCreated, response)
}
// UpdateObject обрабатывает PUT /objects/{id}
func (h *ObjectHandler) UpdateObject(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32)
if err != nil {
http.Error(w, "Invalid object ID", http.StatusBadRequest)
return
}
var req UpdateObjectRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
response, err := h.objectService.UpdateObject(r.Context(), uint(id), &req)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusOK, response)
}
// DeleteObject обрабатывает DELETE /objects/{id}
func (h *ObjectHandler) DeleteObject(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32)
if err != nil {
http.Error(w, "Invalid object ID", http.StatusBadRequest)
return
}
if err := h.objectService.DeleteObject(r.Context(), uint(id)); err != nil {
h.handleError(w, err)
return
}
w.WriteHeader(http.StatusNoContent)
}
// ListObjects обрабатывает GET /objects
func (h *ObjectHandler) ListObjects(w http.ResponseWriter, r *http.Request) {
req := &ListObjectsRequest{
Page: h.getQueryParamInt(r, "page", 1),
PageSize: h.getQueryParamInt(r, "page_size", 10),
Type: r.URL.Query().Get("type"),
Query: r.URL.Query().Get("q"),
}
if statusStr := r.URL.Query().Get("is_active"); statusStr != "" {
isActive, err := strconv.ParseBool(statusStr)
if err == nil {
req.Status = &isActive
}
}
response, err := h.objectService.ListObjects(r.Context(), req)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusOK, response)
}
// GetObjectsByOwner обрабатывает GET /objects/owner/{ownerId}
func (h *ObjectHandler) GetObjectsByOwner(w http.ResponseWriter, r *http.Request) {
ownerID, err := strconv.ParseUint(chi.URLParam(r, "ownerId"), 10, 32)
if err != nil {
http.Error(w, "Invalid owner ID", http.StatusBadRequest)
return
}
page := h.getQueryParamInt(r, "page", 1)
pageSize := h.getQueryParamInt(r, "page_size", 10)
response, err := h.objectService.GetObjectsByOwner(r.Context(), uint(ownerID), page, pageSize)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusOK, response)
}
// SearchObjects обрабатывает GET /objects/search
func (h *ObjectHandler) SearchObjects(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query().Get("q")
if query == "" {
http.Error(w, "Search query is required", http.StatusBadRequest)
return
}
page := h.getQueryParamInt(r, "page", 1)
pageSize := h.getQueryParamInt(r, "page_size", 10)
response, err := h.objectService.SearchObjects(r.Context(), query, page, pageSize)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusOK, response)
}
// GetNearbyObjects обрабатывает GET /objects/nearby
func (h *ObjectHandler) GetNearbyObjects(w http.ResponseWriter, r *http.Request) {
lat, err := strconv.ParseFloat(r.URL.Query().Get("lat"), 64)
if err != nil {
http.Error(w, "Invalid latitude", http.StatusBadRequest)
return
}
lng, err := strconv.ParseFloat(r.URL.Query().Get("lng"), 64)
if err != nil {
http.Error(w, "Invalid longitude", http.StatusBadRequest)
return
}
radius, err := strconv.ParseFloat(r.URL.Query().Get("radius"), 64)
if err != nil || radius <= 0 {
radius = 1000 // По умолчанию 1 км
}
page := h.getQueryParamInt(r, "page", 1)
pageSize := h.getQueryParamInt(r, "page_size", 10)
response, err := h.objectService.GetNearbyObjects(r.Context(), lat, lng, radius, page, pageSize)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusOK, response)
}
// CreateFeedback обрабатывает POST /objects/{id}/feedbacks
func (h *ObjectHandler) CreateFeedback(w http.ResponseWriter, r *http.Request) {
objectID, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32)
if err != nil {
http.Error(w, "Invalid object ID", http.StatusBadRequest)
return
}
var req CreateFeedbackRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
req.ObjectID = uint(objectID)
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
response, err := h.objectService.CreateFeedback(r.Context(), &req, userID)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusCreated, response)
}
// CreateRatingVote обрабатывает POST /objects/{id}/ratings
func (h *ObjectHandler) CreateRatingVote(w http.ResponseWriter, r *http.Request) {
objectID, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 32)
if err != nil {
http.Error(w, "Invalid object ID", http.StatusBadRequest)
return
}
var req CreateRatingVoteRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
req.TargetID = uint(objectID)
userID, ok := r.Context().Value(middleware.UserIDKey).(uint)
if !ok {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
response, err := h.objectService.CreateRatingVote(r.Context(), &req, userID)
if err != nil {
h.handleError(w, err)
return
}
h.respondWithJSON(w, http.StatusCreated, response)
}
// Вспомогательные методы
func (h *ObjectHandler) respondWithJSON(w http.ResponseWriter, status int, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(data); err != nil {
http.Error(w, "Failed to encode response", http.StatusInternalServerError)
}
}
func (h *ObjectHandler) handleError(w http.ResponseWriter, err error) {
switch err {
case ErrObjectNotFound:
http.Error(w, err.Error(), http.StatusNotFound)
case ErrInvalidOwnerID, ErrShortNameRequired, ErrAlreadyVoted:
http.Error(w, err.Error(), http.StatusBadRequest)
case ErrNotImplemented:
http.Error(w, err.Error(), http.StatusNotImplemented)
default:
http.Error(w, "Internal server error", http.StatusInternalServerError)
}
}
func (h *ObjectHandler) getQueryParamInt(r *http.Request, key string, defaultValue int) int {
value := r.URL.Query().Get(key)
if value == "" {
return defaultValue
}
intValue, err := strconv.Atoi(value)
if err != nil {
return defaultValue
}
return intValue
}