From 7e98ea66d2d10ccd6d4e81d24c98c5861f5ea600 Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Sun, 15 Mar 2026 22:14:49 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- svc/main.go | 2 +- svc/routes/product_images.go | 82 +++++++++------ ui/src/pages/ProductStockByAttributes.vue | 115 +++++++++++++--------- ui/src/pages/ProductStockQuery.vue | 112 +++++++++++++-------- 4 files changed, 193 insertions(+), 118 deletions(-) diff --git a/svc/main.go b/svc/main.go index 7e818a4..90c8479 100644 --- a/svc/main.go +++ b/svc/main.go @@ -579,7 +579,7 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router bindV3(r, pgDB, "/api/product-images/{id}/content", "GET", "order", "view", - wrapV3(http.HandlerFunc(routes.GetProductImageContentHandler(pgDB))), + http.HandlerFunc(routes.GetProductImageContentHandler(pgDB)), ) // ============================================================ diff --git a/svc/routes/product_images.go b/svc/routes/product_images.go index 1538a69..a7b7632 100644 --- a/svc/routes/product_images.go +++ b/svc/routes/product_images.go @@ -161,6 +161,10 @@ func GetProductImagesHandler(pg *sql.DB) http.HandlerFunc { if dim1 == "" { dim1 = strings.TrimSpace(r.URL.Query().Get("color")) } + dim1ID := strings.TrimSpace(r.URL.Query().Get("dim1_id")) + if dim1ID == "" { + dim1ID = strings.TrimSpace(r.URL.Query().Get("itemdim1")) + } dim3 := strings.TrimSpace(r.URL.Query().Get("dim3")) if dim3 == "" { dim3 = strings.TrimSpace(r.URL.Query().Get("yaka")) @@ -168,6 +172,10 @@ func GetProductImagesHandler(pg *sql.DB) http.HandlerFunc { if dim3 == "" { dim3 = strings.TrimSpace(r.URL.Query().Get("renk2")) } + dim3ID := strings.TrimSpace(r.URL.Query().Get("dim3_id")) + if dim3ID == "" { + dim3ID = strings.TrimSpace(r.URL.Query().Get("itemdim3")) + } if code == "" { @@ -224,7 +232,9 @@ ORDER BY "req_id", reqID, "code", code, "dim1", dim1, + "dim1_id", dim1ID, "dim3", dim3, + "dim3_id", dim3ID, "err", err.Error(), ) @@ -240,7 +250,9 @@ ORDER BY matchedByName := make([]ProductImageItem, 0, 16) matchedByNameDim1Only := make([]ProductImageItem, 0, 16) dim1Upper := strings.ToUpper(strings.TrimSpace(dim1)) + dim1IDUpper := strings.ToUpper(strings.TrimSpace(dim1ID)) dim3Upper := strings.ToUpper(strings.TrimSpace(dim3)) + dim3IDUpper := strings.ToUpper(strings.TrimSpace(dim3ID)) for rows.Next() { @@ -264,12 +276,16 @@ ORDER BY rowDim1ByID[it.ID] = strings.TrimSpace(rowDim1) dimMatched := true - if dim1Upper != "" { + if dim1IDUpper != "" { + dimMatched = dimMatched && (rowDim1 == dim1IDUpper) + } else if dim1Upper != "" { // Bazı eski kayıtlarda dimval1 gerçek renk kodu yerine numeric id tutulmuş olabilir. // Bu yüzden dimval karşılaştırması yardımcı; asıl fallback file_name token eşleşmesidir. dimMatched = dimMatched && (rowDim1 == dim1Upper) } - if dim3Upper != "" { + if dim3IDUpper != "" { + dimMatched = dimMatched && (rowDim3 == dim3IDUpper || rowDim2 == dim3IDUpper) + } else if dim3Upper != "" { dimMatched = dimMatched && (rowDim3 == dim3Upper || rowDim2 == dim3Upper) } if dimMatched { @@ -284,14 +300,14 @@ ORDER BY } } - if dim1Upper != "" || dim3Upper != "" { - if dim3Upper != "" { + if dim1Upper != "" || dim1IDUpper != "" || dim3Upper != "" || dim3IDUpper != "" { + if dim3Upper != "" || dim3IDUpper != "" { // dim3 verildiginde kesin varyant listesi oncelikli. - if len(matchedByName) > 0 { + if dim3Upper != "" && len(matchedByName) > 0 { items = matchedByName } else if len(matchedByDim) > 0 { items = matchedByDim - } else if len(matchedByNameDim1Only) > 0 { + } else if dim3Upper != "" && len(matchedByNameDim1Only) > 0 { // dim3 pattern'i olmayan legacy tek-renk isimlerde dim1-only fallback. hasDim3Pattern := false for _, it := range matchedByNameDim1Only { @@ -321,36 +337,40 @@ ORDER BY items = []ProductImageItem{} } } else { - targetDimval1 := make(map[string]struct{}, 4) - for _, it := range matchedByName { - if dv := rowDim1ByID[it.ID]; dv != "" { - targetDimval1[dv] = struct{}{} - } - } - if len(targetDimval1) == 0 { - for _, it := range matchedByNameDim1Only { + if dim1IDUpper != "" && len(matchedByDim) > 0 { + items = matchedByDim + } else { + targetDimval1 := make(map[string]struct{}, 4) + for _, it := range matchedByName { 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 && filePrimaryMatchesDim1(it.FileName, dim1Upper) { - clustered = append(clustered, it) + if len(targetDimval1) == 0 { + for _, it := range matchedByNameDim1Only { + if dv := rowDim1ByID[it.ID]; dv != "" { + targetDimval1[dv] = struct{}{} + } } } - 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{} + + if len(targetDimval1) > 0 { + clustered := make([]ProductImageItem, 0, len(items)) + for _, it := range items { + if _, ok := targetDimval1[rowDim1ByID[it.ID]]; ok && filePrimaryMatchesDim1(it.FileName, dim1Upper) { + 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{} + } } } } @@ -359,7 +379,9 @@ ORDER BY "req_id", reqID, "code", code, "dim1", dim1, + "dim1_id", dim1ID, "dim3", dim3, + "dim3_id", dim3ID, "count", len(items), ) diff --git a/ui/src/pages/ProductStockByAttributes.vue b/ui/src/pages/ProductStockByAttributes.vue index 8a51afe..8507ae0 100644 --- a/ui/src/pages/ProductStockByAttributes.vue +++ b/ui/src/pages/ProductStockByAttributes.vue @@ -184,12 +184,12 @@
@@ -465,8 +465,8 @@ function sortByTotalQtyDesc(a, b) { return String(a?.key || '').localeCompare(String(b?.key || ''), 'tr', { sensitivity: 'base' }) } -function buildImageKey(code, color, secondColor = '') { - return `${String(code || '').trim().toUpperCase()}::${String(color || '').trim().toUpperCase()}::${String(secondColor || '').trim().toUpperCase()}` +function buildImageKey(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + return `${String(code || '').trim().toUpperCase()}::${String(color || '').trim().toUpperCase()}::${String(secondColor || '').trim().toUpperCase()}::${String(dim1Id || '').trim().toUpperCase()}::${String(dim3Id || '').trim().toUpperCase()}` } function normalizeImageDim3(value) { @@ -485,6 +485,34 @@ function resolvePhotoDim3(item, secondColorDisplay = '') { ) } +function resolvePhotoDim1ID(item) { + const candidates = [ + item?.ItemDim1Code, + item?.itemDim1Code, + item?.ITEMDIM1CODE, + item?.RenkID, + item?.Renk_Id + ] + for (const value of candidates) { + const s = String(value || '').trim() + if (/^\d+$/.test(s)) return s + } + return '' +} + +function resolvePhotoDim3ID(item) { + const candidates = [ + item?.ItemDim3Code, + item?.itemDim3Code, + item?.ITEMDIM3CODE + ] + for (const value of candidates) { + const s = String(value || '').trim() + if (/^\d+$/.test(s)) return s + } + return '' +} + function buildDim3Candidates(secondColor) { const secondTrim = normalizeImageDim3(secondColor) if (!secondTrim) return [''] @@ -493,10 +521,12 @@ function buildDim3Candidates(secondColor) { return Array.from(set) } -async function fetchProductImageList(codeTrim, colorTrim, secondTrim) { +async function fetchProductImageList(codeTrim, colorTrim, secondTrim, dim1IdTrim = '', dim3IdTrim = '') { const dim3Candidates = buildDim3Candidates(secondTrim) for (const dim3Candidate of dim3Candidates) { const params = { code: codeTrim, dim1: colorTrim } + if (String(dim1IdTrim || '').trim()) params.dim1_id = String(dim1IdTrim || '').trim() + if (String(dim3IdTrim || '').trim()) params.dim3_id = String(dim3IdTrim || '').trim() if (dim3Candidate) params.dim3 = dim3Candidate const res = await api.get('/product-images', { params }) const list = Array.isArray(res?.data) ? res.data : [] @@ -550,6 +580,8 @@ function resolveProductImageUrl(item) { async function resolveProductImageUrlForCarousel(item) { const resolved = resolveProductImageUrl(item) + const publicUrl = String(resolved.publicUrl || '').trim() + if (publicUrl) return publicUrl const contentUrl = String(resolved.contentUrl || '').trim() if (contentUrl) { try { @@ -564,50 +596,31 @@ async function resolveProductImageUrlForCarousel(item) { // fall through to public url } } - return String(resolved.publicUrl || contentUrl || '').trim() + return String(contentUrl || '').trim() } -function getProductImageUrl(code, color, secondColor = '') { - const key = buildImageKey(code, color, secondColor) +function getProductImageUrl(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) const existing = productImageCache.value[key] if (existing !== undefined) return existing || '' - void ensureProductImage(code, color, secondColor) + void ensureProductImage(code, color, secondColor, dim1Id, dim3Id) return '' } -async function onProductImageError(code, color, secondColor = '') { - const key = buildImageKey(code, color, secondColor) - const fallback = String(productImageFallbackByKey.value[key] || '') - if (fallback && !productImageContentLoading.value[key]) { - productImageContentLoading.value[key] = true - try { - const blobRes = await api.get(fallback, { - baseURL: '', - responseType: 'blob' - }) - const blob = blobRes?.data - if (blob instanceof Blob) { - const objectUrl = URL.createObjectURL(blob) - productImageBlobUrls.value.push(objectUrl) - productImageCache.value[key] = objectUrl - return - } - } catch { - // no-op - } finally { - delete productImageContentLoading.value[key] - } - } +async function onProductImageError(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) productImageCache.value[key] = '' } -async function ensureProductImage(code, color, secondColor = '') { - const key = buildImageKey(code, color, secondColor) +async function ensureProductImage(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) const codeTrim = String(code || '').trim().toUpperCase() const colorTrim = String(color || '').trim().toUpperCase() const secondTrim = String(secondColor || '').trim().toUpperCase() - const listKey = buildImageKey(codeTrim, colorTrim, secondTrim) + const dim1IDTrim = String(dim1Id || '').trim().toUpperCase() + const dim3IDTrim = String(dim3Id || '').trim().toUpperCase() + const listKey = buildImageKey(codeTrim, colorTrim, secondTrim, dim1IDTrim, dim3IDTrim) if (!codeTrim) { productImageCache.value[key] = '' return '' @@ -629,7 +642,7 @@ async function ensureProductImage(code, color, secondColor = '') { await new Promise((resolve) => imageListWaitQueue.push(resolve)) } imageListActiveRequests++ - productImageListByCode.value[listKey] = await fetchProductImageList(codeTrim, colorTrim, secondTrim) + productImageListByCode.value[listKey] = await fetchProductImageList(codeTrim, colorTrim, secondTrim, dim1IDTrim, dim3IDTrim) } catch (err) { productImageListByCode.value[listKey] = [] const status = Number(err?.response?.status || 0) @@ -656,8 +669,8 @@ async function ensureProductImage(code, color, secondColor = '') { const resolved = resolveProductImageUrl(first) - productImageCache.value[key] = resolved.contentUrl || resolved.publicUrl || '' - productImageFallbackByKey.value[key] = resolved.contentUrl || '' + productImageCache.value[key] = resolved.publicUrl || resolved.contentUrl || '' + productImageFallbackByKey.value[key] = resolved.publicUrl ? '' : (resolved.contentUrl || '') } catch (err) { console.warn('[ProductStockByAttributes] product image fetch failed', { code, color, err }) productImageCache.value[key] = '' @@ -779,6 +792,8 @@ const level1Groups = computed(() => { const colorDesc = String(item.Renk_Aciklamasi || '').trim() const secondColor = String(item.Yaka || '').trim() const photoDim3 = resolvePhotoDim3(item, secondColor) + const photoDim1ID = resolvePhotoDim1ID(item) + const photoDim3ID = resolvePhotoDim3ID(item) const depoKodu = String(item.Depo_Kodu || '').trim() const depoAdi = String(item.Depo_Adi || '').trim() const urunAnaGrubu = String(item.URUN_ANA_GRUBU || '').trim() @@ -808,7 +823,7 @@ const level1Groups = computed(() => { } l1.totalQty += qty - const l2Key = `${colorCode}|${secondColor}|${photoDim3}` + const l2Key = `${colorCode}|${secondColor}|${photoDim3}|${photoDim1ID}|${photoDim3ID}` if (!l1.childrenMap.has(l2Key)) { l1.childrenMap.set(l2Key, { key: `L2|${productCode}|${l2Key}`, @@ -816,6 +831,8 @@ const level1Groups = computed(() => { colorDesc, secondColor, photoDim3, + photoDim1ID, + photoDim3ID, urunAnaGrubu, urunAltGrubu, urunIcerigi, @@ -1074,7 +1091,7 @@ async function fetchStockByAttributes() { function onLevel2Click(productCode, grp2) { toggleOpen(grp2.key) if (isOpen(grp2.key)) { - void ensureProductImage(productCode, grp2.colorCode, grp2.photoDim3 || grp2.secondColor) + void ensureProductImage(productCode, grp2.colorCode, grp2.photoDim3 || grp2.secondColor, grp2.photoDim1ID || '', grp2.photoDim3ID || '') } } @@ -1083,28 +1100,36 @@ async function openProductCard(grp1, grp2) { const colorCode = String(grp2?.colorCode || '').trim() const secondColor = String(grp2?.secondColor || '').trim() const photoDim3 = String(grp2?.photoDim3 || secondColor).trim() - const listKey = buildImageKey(productCode, colorCode, photoDim3) + const photoDim1ID = String(grp2?.photoDim1ID || '').trim() + const photoDim3ID = String(grp2?.photoDim3ID || '').trim() + const listKey = buildImageKey(productCode, colorCode, photoDim3, photoDim1ID, photoDim3ID) const codeTrim = String(productCode || '').trim().toUpperCase() const colorTrim = String(colorCode || '').trim().toUpperCase() const secondTrim = String(photoDim3 || '').trim().toUpperCase() + const dim1IDTrim = String(photoDim1ID || '').trim().toUpperCase() + const dim3IDTrim = String(photoDim3ID || '').trim().toUpperCase() - await ensureProductImage(productCode, colorCode, photoDim3) + await ensureProductImage(productCode, colorCode, photoDim3, photoDim1ID, photoDim3ID) let list = Array.isArray(productImageListByCode.value[listKey]) ? productImageListByCode.value[listKey] : [] console.info('[ProductStockByAttributes][openProductCard] request', { productCode, colorCode, secondColor, + dim1ID: dim1IDTrim, + dim3ID: dim3IDTrim, listKey, cachedListCount: list.length }) if (!list.length && codeTrim) { try { - list = await fetchProductImageList(codeTrim, colorTrim, secondTrim) + list = await fetchProductImageList(codeTrim, colorTrim, secondTrim, dim1IDTrim, dim3IDTrim) productImageListByCode.value[listKey] = list console.info('[ProductStockByAttributes][openProductCard] refetch', { productCode: codeTrim, dim1: colorTrim, + dim1ID: dim1IDTrim, dim3: secondTrim, + dim3ID: dim3IDTrim, fetchedCount: list.length, fileNames: list.map((x) => String(x?.file_name || x?.FileName || '').trim()).filter(Boolean) }) @@ -1132,7 +1157,7 @@ async function openProductCard(grp1, grp2) { const uniqueImages = Array.from(new Set(images)) if (!uniqueImages.length) { - const single = getProductImageUrl(productCode, colorCode, photoDim3) + const single = getProductImageUrl(productCode, colorCode, photoDim3, photoDim1ID, photoDim3ID) if (single) uniqueImages.push(single) } diff --git a/ui/src/pages/ProductStockQuery.vue b/ui/src/pages/ProductStockQuery.vue index b323f4c..158ceb3 100644 --- a/ui/src/pages/ProductStockQuery.vue +++ b/ui/src/pages/ProductStockQuery.vue @@ -182,12 +182,12 @@
@@ -458,8 +458,8 @@ function sortByColorCodeAsc(a, b) { return compareCodeLike(a?.secondColor, b?.secondColor) } -function buildImageKey(code, color, secondColor = '') { - return `${String(code || '').trim().toUpperCase()}::${String(color || '').trim().toUpperCase()}::${String(secondColor || '').trim().toUpperCase()}` +function buildImageKey(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + return `${String(code || '').trim().toUpperCase()}::${String(color || '').trim().toUpperCase()}::${String(secondColor || '').trim().toUpperCase()}::${String(dim1Id || '').trim().toUpperCase()}::${String(dim3Id || '').trim().toUpperCase()}` } function normalizeImageDim3(value) { @@ -478,6 +478,34 @@ function resolvePhotoDim3(item, secondColorDisplay = '') { ) } +function resolvePhotoDim1ID(item) { + const candidates = [ + item?.ItemDim1Code, + item?.itemDim1Code, + item?.ITEMDIM1CODE, + item?.RenkID, + item?.Renk_Id + ] + for (const value of candidates) { + const s = String(value || '').trim() + if (/^\d+$/.test(s)) return s + } + return '' +} + +function resolvePhotoDim3ID(item) { + const candidates = [ + item?.ItemDim3Code, + item?.itemDim3Code, + item?.ITEMDIM3CODE + ] + for (const value of candidates) { + const s = String(value || '').trim() + if (/^\d+$/.test(s)) return s + } + return '' +} + function buildDim3Candidates(secondColor) { const secondTrim = normalizeImageDim3(secondColor) if (!secondTrim) return [''] @@ -486,10 +514,12 @@ function buildDim3Candidates(secondColor) { return Array.from(set) } -async function fetchProductImageList(codeTrim, colorTrim, secondTrim) { +async function fetchProductImageList(codeTrim, colorTrim, secondTrim, dim1IdTrim = '', dim3IdTrim = '') { const dim3Candidates = buildDim3Candidates(secondTrim) for (const dim3Candidate of dim3Candidates) { const params = { code: codeTrim, dim1: colorTrim } + if (String(dim1IdTrim || '').trim()) params.dim1_id = String(dim1IdTrim || '').trim() + if (String(dim3IdTrim || '').trim()) params.dim3_id = String(dim3IdTrim || '').trim() if (dim3Candidate) params.dim3 = dim3Candidate const res = await api.get('/product-images', { params }) const list = Array.isArray(res?.data) ? res.data : [] @@ -537,6 +567,8 @@ function resolveProductImageUrl(item) { async function resolveProductImageUrlForCarousel(item) { const resolved = resolveProductImageUrl(item) + const publicUrl = String(resolved.publicUrl || '').trim() + if (publicUrl) return publicUrl const contentUrl = String(resolved.contentUrl || '').trim() if (contentUrl) { try { @@ -551,46 +583,30 @@ async function resolveProductImageUrlForCarousel(item) { // fall through to public url } } - return String(resolved.publicUrl || contentUrl || '').trim() + return String(contentUrl || '').trim() } -function getProductImageUrl(code, color, secondColor = '') { - const key = buildImageKey(code, color, secondColor) +function getProductImageUrl(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) const existing = productImageCache.value[key] if (existing !== undefined) return existing || '' - void ensureProductImage(code, color, secondColor) + void ensureProductImage(code, color, secondColor, dim1Id, dim3Id) return '' } -async function onProductImageError(code, color, secondColor = '') { - const key = buildImageKey(code, color, secondColor) - const fallback = String(productImageFallbackByKey.value[key] || '') - if (fallback && !productImageContentLoading.value[key]) { - productImageContentLoading.value[key] = true - try { - const blobRes = await api.get(fallback, { baseURL: '', responseType: 'blob' }) - const blob = blobRes?.data - if (blob instanceof Blob) { - const objectUrl = URL.createObjectURL(blob) - productImageBlobUrls.value.push(objectUrl) - productImageCache.value[key] = objectUrl - return - } - } catch { - // no-op - } finally { - delete productImageContentLoading.value[key] - } - } +async function onProductImageError(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) productImageCache.value[key] = '' } -async function ensureProductImage(code, color, secondColor = '') { - const key = buildImageKey(code, color, secondColor) +async function ensureProductImage(code, color, secondColor = '', dim1Id = '', dim3Id = '') { + const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) const codeTrim = String(code || '').trim().toUpperCase() const colorTrim = String(color || '').trim().toUpperCase() const secondTrim = String(secondColor || '').trim().toUpperCase() - const listKey = buildImageKey(codeTrim, colorTrim, secondTrim) + const dim1IDTrim = String(dim1Id || '').trim().toUpperCase() + const dim3IDTrim = String(dim3Id || '').trim().toUpperCase() + const listKey = buildImageKey(codeTrim, colorTrim, secondTrim, dim1IDTrim, dim3IDTrim) if (!codeTrim) { productImageCache.value[key] = '' return '' @@ -612,7 +628,7 @@ async function ensureProductImage(code, color, secondColor = '') { await new Promise((resolve) => imageListWaitQueue.push(resolve)) } imageListActiveRequests++ - productImageListByCode.value[listKey] = await fetchProductImageList(codeTrim, colorTrim, secondTrim) + productImageListByCode.value[listKey] = await fetchProductImageList(codeTrim, colorTrim, secondTrim, dim1IDTrim, dim3IDTrim) } catch (err) { productImageListByCode.value[listKey] = [] const status = Number(err?.response?.status || 0) @@ -637,8 +653,8 @@ async function ensureProductImage(code, color, secondColor = '') { const first = list[0] || null const resolved = resolveProductImageUrl(first) - productImageCache.value[key] = resolved.contentUrl || resolved.publicUrl || '' - productImageFallbackByKey.value[key] = resolved.contentUrl || '' + productImageCache.value[key] = resolved.publicUrl || resolved.contentUrl || '' + productImageFallbackByKey.value[key] = resolved.publicUrl ? '' : (resolved.contentUrl || '') } catch (err) { console.warn('[ProductStockQuery] product image fetch failed', { code, color, err }) productImageCache.value[key] = '' @@ -760,6 +776,8 @@ const level1Groups = computed(() => { const colorDesc = String(item.Renk_Aciklamasi || '').trim() const secondColor = String(item.Yaka || '').trim() const photoDim3 = resolvePhotoDim3(item, secondColor) + const photoDim1ID = resolvePhotoDim1ID(item) + const photoDim3ID = resolvePhotoDim3ID(item) const depoKodu = String(item.Depo_Kodu || '').trim() const depoAdi = String(item.Depo_Adi || '').trim() const kategori = String(item.YETISKIN_GARSON || '').trim() @@ -790,7 +808,7 @@ const level1Groups = computed(() => { } l1.totalQty += qty - const l2Key = `${colorCode}|${secondColor}|${photoDim3}` + const l2Key = `${colorCode}|${secondColor}|${photoDim3}|${photoDim1ID}|${photoDim3ID}` if (!l1.childrenMap.has(l2Key)) { l1.childrenMap.set(l2Key, { key: `L2|${productCode}|${l2Key}`, @@ -798,6 +816,8 @@ const level1Groups = computed(() => { colorDesc, secondColor, photoDim3, + photoDim1ID, + photoDim3ID, kategori, urunAnaGrubu, urunAltGrubu, @@ -946,7 +966,7 @@ async function fetchStockByCode() { function onLevel2Click(productCode, grp2) { toggleOpen(grp2.key) if (isOpen(grp2.key)) { - void ensureProductImage(productCode, grp2.colorCode, grp2.photoDim3 || grp2.secondColor) + void ensureProductImage(productCode, grp2.colorCode, grp2.photoDim3 || grp2.secondColor, grp2.photoDim1ID || '', grp2.photoDim3ID || '') } } @@ -955,28 +975,36 @@ async function openProductCard(grp1, grp2) { const colorCode = String(grp2?.colorCode || '').trim() const secondColor = String(grp2?.secondColor || '').trim() const photoDim3 = String(grp2?.photoDim3 || secondColor).trim() - const listKey = buildImageKey(productCode, colorCode, photoDim3) + const photoDim1ID = String(grp2?.photoDim1ID || '').trim() + const photoDim3ID = String(grp2?.photoDim3ID || '').trim() + const listKey = buildImageKey(productCode, colorCode, photoDim3, photoDim1ID, photoDim3ID) const codeTrim = String(productCode || '').trim().toUpperCase() const colorTrim = String(colorCode || '').trim().toUpperCase() const secondTrim = String(photoDim3 || '').trim().toUpperCase() + const dim1IDTrim = String(photoDim1ID || '').trim().toUpperCase() + const dim3IDTrim = String(photoDim3ID || '').trim().toUpperCase() - await ensureProductImage(productCode, colorCode, photoDim3) + await ensureProductImage(productCode, colorCode, photoDim3, photoDim1ID, photoDim3ID) let list = Array.isArray(productImageListByCode.value[listKey]) ? productImageListByCode.value[listKey] : [] console.info('[ProductStockQuery][openProductCard] request', { productCode, colorCode, secondColor, + dim1ID: dim1IDTrim, + dim3ID: dim3IDTrim, listKey, cachedListCount: list.length }) if (!list.length && codeTrim) { try { - list = await fetchProductImageList(codeTrim, colorTrim, secondTrim) + list = await fetchProductImageList(codeTrim, colorTrim, secondTrim, dim1IDTrim, dim3IDTrim) productImageListByCode.value[listKey] = list console.info('[ProductStockQuery][openProductCard] refetch', { productCode: codeTrim, dim1: colorTrim, + dim1ID: dim1IDTrim, dim3: secondTrim, + dim3ID: dim3IDTrim, fetchedCount: list.length, fileNames: list.map((x) => String(x?.file_name || x?.FileName || '').trim()).filter(Boolean) }) @@ -1004,7 +1032,7 @@ async function openProductCard(grp1, grp2) { const uniqueImages = Array.from(new Set(images)) if (!uniqueImages.length) { - const single = getProductImageUrl(productCode, colorCode, photoDim3) + const single = getProductImageUrl(productCode, colorCode, photoDim3, photoDim1ID, photoDim3ID) if (single) uniqueImages.push(single) }