Files
bssapp/svc/routes/product_images.go
2026-03-03 23:28:43 +03:00

156 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package routes
import (
"database/sql"
"encoding/json"
"fmt"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/gorilla/mux"
)
type ProductImageItem struct {
ID int64 `json:"id"`
FileName string `json:"file_name"`
FileSize int64 `json:"file_size"`
Storage string `json:"storage_path"`
ContentURL string `json:"content_url"`
}
// GET /api/product-images?code=...&color=...
func GetProductImagesHandler(pg *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
code := strings.TrimSpace(r.URL.Query().Get("code"))
color := strings.TrimSpace(r.URL.Query().Get("color"))
if code == "" {
http.Error(w, "Eksik parametre: code gerekli", http.StatusBadRequest)
return
}
query := `
SELECT
b.id,
b.file_name,
COALESCE(b.file_size, 0) AS file_size,
COALESCE(b.storage_path, '') AS storage_path
FROM dfblob b
JOIN mmitem i
ON i.id = b.src_id
WHERE b.typ = 'img'
AND b.src_table = 'mmitem'
AND i.code = $1
AND ($2 = '' OR b.file_name ILIKE '%' || '-' || $2 || '-%')
ORDER BY COALESCE(b.sort_order, 999999), b.zlins_dttm DESC, b.id DESC
`
rows, err := pg.Query(query, code, color)
if err != nil {
http.Error(w, "Görsel sorgu hatası: "+err.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
items := make([]ProductImageItem, 0, 16)
for rows.Next() {
var it ProductImageItem
if err := rows.Scan(&it.ID, &it.FileName, &it.FileSize, &it.Storage); err != nil {
continue
}
it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID)
items = append(items, it)
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
_ = json.NewEncoder(w).Encode(items)
}
}
// GET /api/product-images/{id}/content
func GetProductImageContentHandler(pg *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
idStr := mux.Vars(r)["id"]
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil || id <= 0 {
http.Error(w, "Geçersiz görsel id", http.StatusBadRequest)
return
}
var (
fileName string
storagePath string
storedInDB bool
binData []byte
)
err = pg.QueryRow(`
SELECT
COALESCE(file_name, ''),
COALESCE(storage_path, ''),
COALESCE(stored_in_db, false),
bin
FROM dfblob
WHERE id = $1
AND typ = 'img'
`, id).Scan(&fileName, &storagePath, &storedInDB, &binData)
if err != nil {
if err == sql.ErrNoRows {
http.NotFound(w, r)
return
}
http.Error(w, "Görsel okunamadı: "+err.Error(), http.StatusInternalServerError)
return
}
if storedInDB && len(binData) > 0 {
w.Header().Set("Content-Type", http.DetectContentType(binData))
w.Header().Set("Cache-Control", "public, max-age=3600")
_, _ = w.Write(binData)
return
}
resolved := resolveStoragePath(storagePath)
if resolved == "" {
http.NotFound(w, r)
return
}
w.Header().Set("Cache-Control", "public, max-age=3600")
http.ServeFile(w, r, resolved)
}
}
func resolveStoragePath(storagePath string) string {
raw := strings.TrimSpace(storagePath)
if raw == "" {
return ""
}
raw = strings.TrimPrefix(raw, "./")
candidates := []string{
filepath.Clean(storagePath),
filepath.Clean(raw),
filepath.Join(".", raw),
filepath.Join("..", raw),
}
if root := strings.TrimSpace(os.Getenv("BLOB_ROOT")); root != "" {
candidates = append(candidates, filepath.Join(root, raw))
}
for _, p := range candidates {
if p == "" {
continue
}
if st, err := os.Stat(p); err == nil && !st.IsDir() {
return p
}
}
return ""
}