diff --git a/svc/routes/product_images.go b/svc/routes/product_images.go index c22a5cb..097cff3 100644 --- a/svc/routes/product_images.go +++ b/svc/routes/product_images.go @@ -76,12 +76,23 @@ func imageFileMatches(fileName, dim1, dim3 string) bool { return false } + matchesToken := func(token, target string) bool { + if token == target { + return true + } + // "002" filtresi, dosya adindaki "002_1" gibi varyantlari da yakalamali. + if len(target) == 3 && isAllDigits(target) && strings.HasPrefix(token, target+"_") { + return true + } + return false + } + hasToken := func(target string) bool { if target == "" { return true } for _, t := range tokens { - if t == target { + if matchesToken(t, target) { return true } } @@ -236,52 +247,73 @@ ORDER BY } if dim1Upper != "" || dim3Upper != "" { - targetDimval1 := make(map[string]struct{}, 4) - for _, it := range matchedByName { - if dv := rowDim1ByID[it.ID]; dv != "" { - targetDimval1[dv] = struct{}{} + if dim3Upper != "" { + // dim3 verildiginde kesin varyant listesi oncelikli. + if len(matchedByName) > 0 { + items = matchedByName + } else if len(matchedByDim) > 0 { + items = matchedByDim + } else if len(matchedByNameDim1Only) > 0 { + // dim3 pattern'i olmayan legacy tek-renk isimlerde dim1-only fallback. + hasDim3Pattern := false + for _, it := range matchedByNameDim1Only { + if imageFileHasDim3Pattern(it.FileName) { + hasDim3Pattern = true + break + } + } + if !hasDim3Pattern { + targetDimval1 := make(map[string]struct{}, 4) + for _, it := range matchedByNameDim1Only { + if dv := rowDim1ByID[it.ID]; dv != "" { + targetDimval1[dv] = struct{}{} + } + } + clustered := make([]ProductImageItem, 0, len(items)) + for _, it := range items { + if _, ok := targetDimval1[rowDim1ByID[it.ID]]; ok { + clustered = append(clustered, it) + } + } + items = clustered + } else { + items = []ProductImageItem{} + } + } else { + items = []ProductImageItem{} } - } - if len(targetDimval1) == 0 && dim3Upper == "" { - for _, it := range matchedByNameDim1Only { + } else { + targetDimval1 := make(map[string]struct{}, 4) + for _, it := range matchedByName { if dv := rowDim1ByID[it.ID]; dv != "" { targetDimval1[dv] = struct{}{} } } - } - if len(targetDimval1) == 0 && dim3Upper != "" && len(matchedByNameDim1Only) > 0 { - hasDim3Pattern := false - for _, it := range matchedByNameDim1Only { - if imageFileHasDim3Pattern(it.FileName) { - hasDim3Pattern = true - break - } - } - if !hasDim3Pattern { + if len(targetDimval1) == 0 { for _, it := range matchedByNameDim1Only { if dv := rowDim1ByID[it.ID]; dv != "" { targetDimval1[dv] = struct{}{} } } } - } - if len(targetDimval1) > 0 { - clustered := make([]ProductImageItem, 0, len(items)) - for _, it := range items { - if _, ok := targetDimval1[rowDim1ByID[it.ID]]; ok { - clustered = append(clustered, it) + if len(targetDimval1) > 0 { + clustered := make([]ProductImageItem, 0, len(items)) + for _, it := range items { + if _, ok := targetDimval1[rowDim1ByID[it.ID]]; ok { + clustered = append(clustered, it) + } } + items = clustered + } else if len(matchedByDim) > 0 { + items = matchedByDim + } else if len(matchedByName) > 0 { + items = matchedByName + } else if len(matchedByNameDim1Only) > 0 { + items = matchedByNameDim1Only + } else { + items = []ProductImageItem{} } - items = clustered - } else if len(matchedByDim) > 0 { - items = matchedByDim - } else if len(matchedByName) > 0 { - items = matchedByName - } else if dim3Upper == "" && len(matchedByNameDim1Only) > 0 { - items = matchedByNameDim1Only - } else { - items = []ProductImageItem{} } } diff --git a/ui/src/pages/ProductStockByAttributes.vue b/ui/src/pages/ProductStockByAttributes.vue index 7351927..1aace4b 100644 --- a/ui/src/pages/ProductStockByAttributes.vue +++ b/ui/src/pages/ProductStockByAttributes.vue @@ -539,6 +539,25 @@ function resolveProductImageUrl(item) { return { contentUrl, publicUrl } } +async function resolveProductImageUrlForCarousel(item) { + const resolved = resolveProductImageUrl(item) + const contentUrl = String(resolved.contentUrl || '').trim() + if (contentUrl) { + try { + const blobRes = await api.get(contentUrl, { baseURL: '', responseType: 'blob' }) + const blob = blobRes?.data + if (blob instanceof Blob) { + const objectUrl = URL.createObjectURL(blob) + productImageBlobUrls.value.push(objectUrl) + return objectUrl + } + } catch { + // fall through to public url + } + } + return String(resolved.publicUrl || contentUrl || '').trim() +} + function getProductImageUrl(code, color, secondColor = '') { const key = buildImageKey(code, color, secondColor) const existing = productImageCache.value[key] @@ -1073,12 +1092,10 @@ async function openProductCard(grp1, grp2) { } } - const images = list - .map((item) => { - const resolved = resolveProductImageUrl(item) - return resolved.publicUrl || resolved.contentUrl || '' - }) - .filter((x) => String(x || '').trim() !== '') + const imageCandidates = await Promise.all( + list.map((item) => resolveProductImageUrlForCarousel(item)) + ) + const images = imageCandidates.filter((x) => String(x || '').trim() !== '') const uniqueImages = Array.from(new Set(images)) if (!uniqueImages.length) { diff --git a/ui/src/pages/ProductStockQuery.vue b/ui/src/pages/ProductStockQuery.vue index bf43f3c..f6685a7 100644 --- a/ui/src/pages/ProductStockQuery.vue +++ b/ui/src/pages/ProductStockQuery.vue @@ -526,6 +526,25 @@ function resolveProductImageUrl(item) { return { contentUrl, publicUrl } } +async function resolveProductImageUrlForCarousel(item) { + const resolved = resolveProductImageUrl(item) + const contentUrl = String(resolved.contentUrl || '').trim() + if (contentUrl) { + try { + const blobRes = await api.get(contentUrl, { baseURL: '', responseType: 'blob' }) + const blob = blobRes?.data + if (blob instanceof Blob) { + const objectUrl = URL.createObjectURL(blob) + productImageBlobUrls.value.push(objectUrl) + return objectUrl + } + } catch { + // fall through to public url + } + } + return String(resolved.publicUrl || contentUrl || '').trim() +} + function getProductImageUrl(code, color, secondColor = '') { const key = buildImageKey(code, color, secondColor) const existing = productImageCache.value[key] @@ -945,12 +964,10 @@ async function openProductCard(grp1, grp2) { } } - const images = list - .map((item) => { - const resolved = resolveProductImageUrl(item) - return resolved.publicUrl || resolved.contentUrl || '' - }) - .filter((x) => String(x || '').trim() !== '') + const imageCandidates = await Promise.all( + list.map((item) => resolveProductImageUrlForCarousel(item)) + ) + const images = imageCandidates.filter((x) => String(x || '').trim() !== '') const uniqueImages = Array.from(new Set(images)) if (!uniqueImages.length) {