From 7889ab0f07fa8ca25631dc25820c521f2d23a2ee Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Mon, 16 Mar 2026 00:00:02 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- ui/src/pages/ProductStockByAttributes.vue | 140 ++++++++++++++++------ ui/src/pages/ProductStockQuery.vue | 140 ++++++++++++++++------ 2 files changed, 212 insertions(+), 68 deletions(-) diff --git a/ui/src/pages/ProductStockByAttributes.vue b/ui/src/pages/ProductStockByAttributes.vue index b686cdd..25f9acd 100644 --- a/ui/src/pages/ProductStockByAttributes.vue +++ b/ui/src/pages/ProductStockByAttributes.vue @@ -251,21 +251,6 @@ -
-
- {{ productCardData.productCode || '-' }} / {{ productCardData.colorCode || '-' }}{{ productCardData.secondColor ? '-' + productCardData.secondColor : '' }} -
-
Toplam Stok: {{ formatNumber(productCardData.totalQty || 0) }}
-
-
- {{ sz }} - {{ Number(productCardData.sizeTotals?.[sz] || 0) > 0 ? formatNumber(productCardData.sizeTotals[sz]) : '-' }} -
-
-
- - -
+
Urun{{ productCardData.productCode || '-' }} / {{ productCardData.colorCode || '-' }}{{ productCardData.secondColor ? '-' + productCardData.secondColor : '' }}
Urun Kodu{{ productCardData.productCode || '-' }}
Urun Renk{{ productCardData.colorCode || '-' }}
Urun 2.Renk{{ productCardData.secondColor || '-' }}
@@ -306,6 +292,17 @@
Drop{{ productCardData.drop || '-' }}
Kumas{{ productCardData.kumas || '-' }}
Karisim{{ productCardData.karisim || '-' }}
+ +
+
Stok Ozet
+
Toplam Stok: {{ formatNumber(productCardData.totalQty || 0) }}
+
+
+ {{ sz }} + {{ Number(productCardData.sizeTotals?.[sz] || 0) > 0 ? formatNumber(productCardData.sizeTotals[sz]) : '-' }} +
+
+
@@ -498,6 +495,34 @@ function parseNumber(value) { return Number.isFinite(n) ? n : 0 } +function firstText(...values) { + for (const value of values) { + const s = String(value || '').trim() + if (s) return s + } + return '' +} + +function resolveKumasValue(item) { + return firstText( + item?.BIRINCI_PARCA_KUMAS, + item?.ProductAtt26Desc, + item?.PRODUCTATT26DESC, + item?.ProductAtt29Desc, + item?.PRODUCTATT29DESC + ) +} + +function resolveKarisimValue(item) { + return firstText( + item?.BIRINCI_PARCA_KARISIM, + item?.ProductAtt29Desc, + item?.PRODUCTATT29DESC, + item?.ProductAtt26Desc, + item?.PRODUCTATT26DESC + ) +} + function sortByTotalQtyDesc(a, b) { const qa = Number(a?.totalQty || 0) const qb = Number(b?.totalQty || 0) @@ -679,7 +704,7 @@ function getProductImageUrl(code, color, secondColor = '', dim1Id = '', dim3Id = async function onProductImageError(code, color, secondColor = '', dim1Id = '', dim3Id = '') { const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) - productImageCache.value[key] = '' + productImageCache.value[key] = String(productImageFallbackByKey.value[key] || '').trim() } async function ensureProductImage(code, color, secondColor = '', dim1Id = '', dim3Id = '') { @@ -737,9 +762,10 @@ async function ensureProductImage(code, color, secondColor = '', dim1Id = '', di const first = list[0] || null const resolved = resolveProductImageUrl(first) + const preferredCardUrl = first ? await resolveProductImageUrlForCarousel(first) : '' - productImageCache.value[key] = resolved.fullUrl || resolved.publicUrl || resolved.thumbUrl || resolved.contentUrl || '' - productImageFallbackByKey.value[key] = resolved.contentUrl || '' + productImageCache.value[key] = String(preferredCardUrl || resolved.fullUrl || resolved.publicUrl || resolved.thumbUrl || resolved.contentUrl || '').trim() + productImageFallbackByKey.value[key] = resolved.fullUrl || resolved.publicUrl || resolved.contentUrl || '' } catch (err) { console.warn('[ProductStockByAttributes] product image fetch failed', { code, color, err }) productImageCache.value[key] = '' @@ -870,8 +896,8 @@ const level1Groups = computed(() => { const urunIcerigi = String(item.URUN_ICERIGI || item.KISA_KAR || '').trim() const fit = String(item.BIRINCI_PARCA_FIT || '').trim() const drop = String(item.DR || '').trim() - const kumas = String(item.BIRINCI_PARCA_KUMAS || '').trim() - const karisim = String(item.BIRINCI_PARCA_KARISIM || '').trim() + const kumas = resolveKumasValue(item) + const karisim = resolveKarisimValue(item) const aciklama = String(item.Madde_Aciklamasi || '').trim() const beden = normalizeSize(item.Beden || '') const qty = parseNumber(item.Kullanilabilir_Envanter) @@ -1762,12 +1788,12 @@ onUnmounted(() => { .product-card-dialog { --pc-media-h: min(70vh, 900px); --pc-media-w: min(74vw, 1220px); - background: #f6f8fc; + background: #f9f8f5; } .product-card-stock { - background: linear-gradient(180deg, #eef3fb 0%, #f8fbff 100%); - border: 1px solid #c8d6ec; + background: linear-gradient(180deg, #f9f6ef 0%, #fffdf9 100%); + border: 1px solid #e4dac7; border-radius: 12px; padding: 14px; } @@ -1779,7 +1805,7 @@ onUnmounted(() => { } .stock-size-chip { - border: 1px solid #d7e2f2; + border: 1px solid #e6dccb; border-radius: 10px; background: #ffffff; padding: 6px 8px; @@ -1813,8 +1839,8 @@ onUnmounted(() => { .product-card-carousel { width: var(--pc-media-w); max-width: 100%; - background: linear-gradient(180deg, #edf2fb 0%, #e4ebf9 100%); - border: 1px solid #c8d6ec; + background: linear-gradient(180deg, #f6f1e6 0%, #efe6d3 100%); + border: 1px solid #e4dac7; } .dialog-image { @@ -1828,7 +1854,7 @@ onUnmounted(() => { height: var(--pc-media-h); overflow: hidden; border-radius: 10px; - background: linear-gradient(180deg, #edf2fb 0%, #e4ebf9 100%); + background: linear-gradient(180deg, #f6f1e6 0%, #efe6d3 100%); display: flex; align-items: center; justify-content: center; @@ -1838,12 +1864,12 @@ onUnmounted(() => { width: var(--pc-media-w); max-width: 100%; height: var(--pc-media-h); - border: 1px dashed #9db5de; + border: 1px dashed #c5b28d; border-radius: 10px; display: flex; align-items: center; justify-content: center; - background: #f2f6fd; + background: #faf6ee; } .image-fullscreen-dialog { @@ -1861,11 +1887,44 @@ onUnmounted(() => { width: min(98vw, 1500px); } +:deep(.image-fullscreen-carousel .q-carousel__slide) { + background: linear-gradient(180deg, #f7f2e7 0%, #efe5d2 100%); +} + +:deep(.image-fullscreen-carousel .q-carousel__navigation) { + bottom: 12px; +} + +:deep(.image-fullscreen-carousel .q-carousel__navigation .q-btn) { + color: rgba(38, 166, 154, 0.42); + transform: scale(1); + transition: transform 0.14s ease, color 0.14s ease; +} + +:deep(.image-fullscreen-carousel .q-carousel__navigation .q-btn--active) { + color: var(--q-primary, #1976d2); + transform: scale(1.28); + text-shadow: 0 0 0.5px currentColor; + filter: drop-shadow(0 0 2px rgba(38, 166, 154, 0.45)); +} + +:deep(.image-fullscreen-carousel .q-carousel__arrow .q-btn) { + color: var(--q-primary, #1976d2); + background: rgba(255, 255, 255, 0.88); + border: 1px solid #d7e2f3; +} + +:deep(.image-fullscreen-carousel .q-carousel__arrow .q-btn:hover) { + color: var(--q-secondary, #26a69a); + border-color: rgba(38, 166, 154, 0.45); + background: rgba(255, 255, 255, 0.98); +} + .image-fullscreen-stage { width: min(96vw, 1400px); height: calc(100vh - 120px); border-radius: 10px; - background: #efe7cc; + background: linear-gradient(180deg, #f1e7d3 0%, #e9dcc4 100%); overflow: hidden; display: flex; align-items: center; @@ -1880,9 +1939,9 @@ onUnmounted(() => { .product-card-fields { grid-column: 1; grid-row: 1; - border: 1px solid #c8d6ec; + border: 1px solid #e4dac7; border-radius: 12px; - background: linear-gradient(180deg, #ffffff 0%, #f7faff 100%); + background: linear-gradient(180deg, #ffffff 0%, #fdfaf4 100%); padding: 12px; height: var(--pc-media-h); overflow: auto; @@ -1893,16 +1952,24 @@ onUnmounted(() => { grid-template-columns: 150px 1fr; gap: 8px; padding: 8px 0; - border-bottom: 1px solid #e4ebf7; + border-bottom: 1px solid #efe5d5; font-size: 13px; } +.field-row.field-row-head { + background: #f8f3e9; + border: 1px solid #e6dccb; + border-radius: 8px; + padding: 8px 10px; + margin-bottom: 8px; +} + .field-row:last-child { border-bottom: none; } .field-row .k { - color: var(--q-primary, #1976d2); + color: #6b5a33; font-weight: 700; } @@ -1911,6 +1978,11 @@ onUnmounted(() => { word-break: break-word; } +.product-card-stock-inline { + border-top: 1px solid #e6dccb; + padding-top: 10px; +} + .q-btn, .q-icon, .product-image-card, diff --git a/ui/src/pages/ProductStockQuery.vue b/ui/src/pages/ProductStockQuery.vue index 729faa2..197c8a7 100644 --- a/ui/src/pages/ProductStockQuery.vue +++ b/ui/src/pages/ProductStockQuery.vue @@ -249,21 +249,6 @@ -
-
- {{ productCardData.productCode || '-' }} / {{ productCardData.colorCode || '-' }}{{ productCardData.secondColor ? '-' + productCardData.secondColor : '' }} -
-
Toplam Stok: {{ formatNumber(productCardData.totalQty || 0) }}
-
-
- {{ sz }} - {{ Number(productCardData.sizeTotals?.[sz] || 0) > 0 ? formatNumber(productCardData.sizeTotals[sz]) : '-' }} -
-
-
- - -
+
Urun{{ productCardData.productCode || '-' }} / {{ productCardData.colorCode || '-' }}{{ productCardData.secondColor ? '-' + productCardData.secondColor : '' }}
Urun Kodu{{ productCardData.productCode || '-' }}
Urun Renk{{ productCardData.colorCode || '-' }}
Urun 2.Renk{{ productCardData.secondColor || '-' }}
@@ -304,6 +290,17 @@
Drop{{ productCardData.drop || '-' }}
Kumas{{ productCardData.kumas || '-' }}
Karisim{{ productCardData.karisim || '-' }}
+ +
+
Stok Ozet
+
Toplam Stok: {{ formatNumber(productCardData.totalQty || 0) }}
+
+
+ {{ sz }} + {{ Number(productCardData.sizeTotals?.[sz] || 0) > 0 ? formatNumber(productCardData.sizeTotals[sz]) : '-' }} +
+
+
@@ -465,6 +462,34 @@ function parseNumber(value) { return Number.isFinite(n) ? n : 0 } +function firstText(...values) { + for (const value of values) { + const s = String(value || '').trim() + if (s) return s + } + return '' +} + +function resolveKumasValue(item) { + return firstText( + item?.BIRINCI_PARCA_KUMAS, + item?.ProductAtt26Desc, + item?.PRODUCTATT26DESC, + item?.ProductAtt29Desc, + item?.PRODUCTATT29DESC + ) +} + +function resolveKarisimValue(item) { + return firstText( + item?.BIRINCI_PARCA_KARISIM, + item?.ProductAtt29Desc, + item?.PRODUCTATT29DESC, + item?.ProductAtt26Desc, + item?.PRODUCTATT26DESC + ) +} + function sortByColorCodeAsc(a, b) { const compareCodeLike = (va, vb) => { const sa = String(va || '').trim() @@ -665,7 +690,7 @@ function getProductImageUrl(code, color, secondColor = '', dim1Id = '', dim3Id = async function onProductImageError(code, color, secondColor = '', dim1Id = '', dim3Id = '') { const key = buildImageKey(code, color, secondColor, dim1Id, dim3Id) - productImageCache.value[key] = '' + productImageCache.value[key] = String(productImageFallbackByKey.value[key] || '').trim() } async function ensureProductImage(code, color, secondColor = '', dim1Id = '', dim3Id = '') { @@ -722,8 +747,9 @@ async function ensureProductImage(code, color, secondColor = '', dim1Id = '', di const first = list[0] || null const resolved = resolveProductImageUrl(first) - productImageCache.value[key] = resolved.fullUrl || resolved.publicUrl || resolved.thumbUrl || resolved.contentUrl || '' - productImageFallbackByKey.value[key] = resolved.contentUrl || '' + const preferredCardUrl = first ? await resolveProductImageUrlForCarousel(first) : '' + productImageCache.value[key] = String(preferredCardUrl || resolved.fullUrl || resolved.publicUrl || resolved.thumbUrl || resolved.contentUrl || '').trim() + productImageFallbackByKey.value[key] = resolved.fullUrl || resolved.publicUrl || resolved.contentUrl || '' } catch (err) { console.warn('[ProductStockQuery] product image fetch failed', { code, color, err }) productImageCache.value[key] = '' @@ -855,8 +881,8 @@ const level1Groups = computed(() => { const urunIcerigi = String(item.URUN_ICERIGI || item.KISA_KAR || '').trim() const fit = String(item.BIRINCI_PARCA_FIT || '').trim() const drop = String(item.DR || '').trim() - const kumas = String(item.BIRINCI_PARCA_KUMAS || '').trim() - const karisim = String(item.BIRINCI_PARCA_KARISIM || '').trim() + const kumas = resolveKumasValue(item) + const karisim = resolveKarisimValue(item) const aciklama = String(item.Madde_Aciklamasi || '').trim() const beden = normalizeSize(item.Beden || '') const qty = parseNumber(item.Kullanilabilir_Envanter) @@ -1618,12 +1644,12 @@ onMounted(() => { .product-card-dialog { --pc-media-h: min(70vh, 900px); --pc-media-w: min(74vw, 1220px); - background: #f6f8fc; + background: #f9f8f5; } .product-card-stock { - background: linear-gradient(180deg, #eef3fb 0%, #f8fbff 100%); - border: 1px solid #c8d6ec; + background: linear-gradient(180deg, #f9f6ef 0%, #fffdf9 100%); + border: 1px solid #e4dac7; border-radius: 12px; padding: 14px; } @@ -1635,7 +1661,7 @@ onMounted(() => { } .stock-size-chip { - border: 1px solid #d7e2f2; + border: 1px solid #e6dccb; border-radius: 10px; background: #ffffff; padding: 6px 8px; @@ -1669,8 +1695,8 @@ onMounted(() => { .product-card-carousel { width: var(--pc-media-w); max-width: 100%; - background: linear-gradient(180deg, #edf2fb 0%, #e4ebf9 100%); - border: 1px solid #c8d6ec; + background: linear-gradient(180deg, #f6f1e6 0%, #efe6d3 100%); + border: 1px solid #e4dac7; } .dialog-image { @@ -1684,7 +1710,7 @@ onMounted(() => { height: var(--pc-media-h); overflow: hidden; border-radius: 10px; - background: linear-gradient(180deg, #edf2fb 0%, #e4ebf9 100%); + background: linear-gradient(180deg, #f6f1e6 0%, #efe6d3 100%); display: flex; align-items: center; justify-content: center; @@ -1694,12 +1720,12 @@ onMounted(() => { width: var(--pc-media-w); max-width: 100%; height: var(--pc-media-h); - border: 1px dashed #9db5de; + border: 1px dashed #c5b28d; border-radius: 10px; display: flex; align-items: center; justify-content: center; - background: #f2f6fd; + background: #faf6ee; } .image-fullscreen-dialog { @@ -1717,11 +1743,44 @@ onMounted(() => { width: min(98vw, 1500px); } +:deep(.image-fullscreen-carousel .q-carousel__slide) { + background: linear-gradient(180deg, #f7f2e7 0%, #efe5d2 100%); +} + +:deep(.image-fullscreen-carousel .q-carousel__navigation) { + bottom: 12px; +} + +:deep(.image-fullscreen-carousel .q-carousel__navigation .q-btn) { + color: rgba(38, 166, 154, 0.42); + transform: scale(1); + transition: transform 0.14s ease, color 0.14s ease; +} + +:deep(.image-fullscreen-carousel .q-carousel__navigation .q-btn--active) { + color: var(--q-primary, #1976d2); + transform: scale(1.28); + text-shadow: 0 0 0.5px currentColor; + filter: drop-shadow(0 0 2px rgba(38, 166, 154, 0.45)); +} + +:deep(.image-fullscreen-carousel .q-carousel__arrow .q-btn) { + color: var(--q-primary, #1976d2); + background: rgba(255, 255, 255, 0.88); + border: 1px solid #d7e2f3; +} + +:deep(.image-fullscreen-carousel .q-carousel__arrow .q-btn:hover) { + color: var(--q-secondary, #26a69a); + border-color: rgba(38, 166, 154, 0.45); + background: rgba(255, 255, 255, 0.98); +} + .image-fullscreen-stage { width: min(96vw, 1400px); height: calc(100vh - 120px); border-radius: 10px; - background: #efe7cc; + background: linear-gradient(180deg, #f1e7d3 0%, #e9dcc4 100%); overflow: hidden; display: flex; align-items: center; @@ -1736,9 +1795,9 @@ onMounted(() => { .product-card-fields { grid-column: 1; grid-row: 1; - border: 1px solid #c8d6ec; + border: 1px solid #e4dac7; border-radius: 12px; - background: linear-gradient(180deg, #ffffff 0%, #f7faff 100%); + background: linear-gradient(180deg, #ffffff 0%, #fdfaf4 100%); padding: 12px; height: var(--pc-media-h); overflow: auto; @@ -1749,16 +1808,24 @@ onMounted(() => { grid-template-columns: 150px 1fr; gap: 8px; padding: 8px 0; - border-bottom: 1px solid #e4ebf7; + border-bottom: 1px solid #efe5d5; font-size: 13px; } +.field-row.field-row-head { + background: #f8f3e9; + border: 1px solid #e6dccb; + border-radius: 8px; + padding: 8px 10px; + margin-bottom: 8px; +} + .field-row:last-child { border-bottom: none; } .field-row .k { - color: var(--q-primary, #1976d2); + color: #6b5a33; font-weight: 700; } @@ -1767,6 +1834,11 @@ onMounted(() => { word-break: break-word; } +.product-card-stock-inline { + border-top: 1px solid #e6dccb; + padding-top: 10px; +} + .q-btn, .q-icon, .product-image-card,