diff --git a/svc/routes/product_images.go b/svc/routes/product_images.go index 2bcd7e5..b52326b 100644 --- a/svc/routes/product_images.go +++ b/svc/routes/product_images.go @@ -25,6 +25,7 @@ type ProductImageItem struct { UUID string `json:"uuid,omitempty"` ThumbURL string `json:"thumb_url,omitempty"` FullURL string `json:"full_url,omitempty"` + StoredInDB bool `json:"stored_in_db,omitempty"` } type ProductImageBatchItem struct { @@ -136,6 +137,24 @@ func extractImageUUID(storagePath, fileName string) string { return "" } +func enrichProductImageItem(it *ProductImageItem) { + if it == nil { + return + } + if u := extractImageUUID(it.Storage, it.FileName); u != "" { + it.UUID = u + it.ThumbURL = "/uploads/image/t300/" + u + ".jpg" + it.FullURL = "/uploads/image/" + u + ".jpg" + } + if it.StoredInDB { + it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID) + return + } + if resolved, _ := resolveStoragePath(it.Storage); resolved != "" { + it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID) + } +} + // POST /api/product-images/batch func PostProductImagesBatchHandler(pg *sql.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -208,6 +227,7 @@ ranked AS ( COALESCE(b.file_name,'') AS file_name, COALESCE(b.file_size,0) AS file_size, COALESCE(b.storage_path,'') AS storage_path, + COALESCE(b.stored_in_db,false) AS stored_in_db, ROW_NUMBER() OVER ( PARTITION BY mi.key ORDER BY @@ -225,7 +245,7 @@ ranked AS ( AND b.typ='img' AND b.src_id=mi.mmitem_id ) -SELECT key, id, file_name, file_size, storage_path +SELECT key, id, file_name, file_size, storage_path, stored_in_db FROM ranked WHERE rn <= 1 ORDER BY key, rn @@ -241,15 +261,10 @@ ORDER BY key, rn for rows.Next() { var key string var it ProductImageItem - if err := rows.Scan(&key, &it.ID, &it.FileName, &it.FileSize, &it.Storage); err != nil { + if err := rows.Scan(&key, &it.ID, &it.FileName, &it.FileSize, &it.Storage, &it.StoredInDB); err != nil { continue } - it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID) - if u := extractImageUUID(it.Storage, it.FileName); u != "" { - it.UUID = u - it.ThumbURL = "/uploads/image/t300/" + u + ".jpg" - it.FullURL = "/uploads/image/" + u + ".jpg" - } + enrichProductImageItem(&it) grouped[key] = append(grouped[key], it) } if err := rows.Err(); err != nil { @@ -339,7 +354,8 @@ SELECT id, COALESCE(file_name,'') AS file_name, COALESCE(file_size,0) AS file_size, - COALESCE(storage_path,'') AS storage_path + COALESCE(storage_path,'') AS storage_path, + COALESCE(stored_in_db,false) AS stored_in_db FROM dfblob WHERE typ='img' AND src_table='mmitem' @@ -370,15 +386,10 @@ ORDER BY 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 { + if err := rows.Scan(&it.ID, &it.FileName, &it.FileSize, &it.Storage, &it.StoredInDB); err != nil { continue } - it.ContentURL = fmt.Sprintf("/api/product-images/%d/content", it.ID) - if u := extractImageUUID(it.Storage, it.FileName); u != "" { - it.UUID = u - it.ThumbURL = "/uploads/image/t300/" + u + ".jpg" - it.FullURL = "/uploads/image/" + u + ".jpg" - } + enrichProductImageItem(&it) items = append(items, it) } if err := rows.Err(); err != nil { @@ -529,6 +540,9 @@ WHERE id = $1 } resolved, _ := resolveStoragePath(storagePath) + if resolved == "" { + resolved, _ = resolveStoragePath(fileName) + } if resolved == "" { http.NotFound(w, r) return diff --git a/ui/src/pages/ProductPerformanceProfitability.vue b/ui/src/pages/ProductPerformanceProfitability.vue index 9e6b309..b5d7454 100644 --- a/ui/src/pages/ProductPerformanceProfitability.vue +++ b/ui/src/pages/ProductPerformanceProfitability.vue @@ -100,6 +100,10 @@ +
+