diff --git a/ui/src/pages/OrderPriceList.vue b/ui/src/pages/OrderPriceList.vue index 6cbc8c1..b1c7022 100644 --- a/ui/src/pages/OrderPriceList.vue +++ b/ui/src/pages/OrderPriceList.vue @@ -70,67 +70,73 @@
- - - - Tumunu Sec - - - Tumunu Temizle - - - - - - - {{ option.label }} - - - +
+ + + + Tumunu Sec + + + Tumunu Temizle + + + + + + + {{ option.label }} + + + - + +
- - - - - Excel'e Aktar - - - - PDF / Yazdir - - - +
+ + + + + Excel'e Aktar + + + + PDF / Yazdir + + + +
- -
- Sayfa {{ currentPage }} / {{ Math.max(1, totalPages || 1) }} - {{ filteredRows.length }} satir +
+ +
+ Sayfa {{ currentPage }} / {{ Math.max(1, totalPages || 1) }} - {{ filteredRows.length }} satir +
@@ -340,10 +346,14 @@ +
+ +
@@ -379,6 +389,99 @@ + + + + +
Urun Karti
+ + +
+ + + + +
+
+ + +
+ +
+
+
+
+ +
+
+ +
+
Urun{{ productCardData.productCode || '-' }} / {{ productCardData.variantCodes || '-' }}
+
Urun Kodu{{ productCardData.productCode || '-' }}
+
Varyant{{ productCardData.variantCodes || '-' }}
+
Marka{{ productCardData.marka || '-' }}
+
Marka Grubu{{ productCardData.brandGroupSelection || '-' }}
+
Kategori{{ productCardData.kategori || '-' }}
+
Urun Ilk Grubu{{ productCardData.urunIlkGrubu || '-' }}
+
Urun Ana Grubu{{ productCardData.urunAnaGrubu || '-' }}
+
Urun Alt Grubu{{ productCardData.urunAltGrubu || '-' }}
+
Icerik{{ productCardData.icerik || '-' }}
+
Karisim{{ productCardData.karisim || '-' }}
+
Kampanya{{ productCardData.campaignLabel || '-' }}
+
Stok{{ formatStock(productCardData.stockQty || 0) }}
+
+
+
+
+
+ + + + +
Urun Fotografi
+ + +
+ + + + +
+ +
+
+
+
+
+
@@ -418,10 +521,19 @@ const serverFilterLoading = ref({}) const serverFilterLastQuery = ref({}) const filterSearch = ref({ productCode: '', urunIlkGrubu: '', urunAnaGrubu: '' }) const imageCache = new Map() +const imageListCache = new Map() const mainTableRef = ref(null) const topScrollRef = ref(null) let syncingScroll = false +const productCardDialog = ref(false) +const productCardData = ref({}) +const productCardImages = ref([]) +const productCardSlide = ref(0) +const productImageFullscreenDialog = ref(false) +const productImageFullscreenSlide = ref(0) +const fullscreenImages = computed(() => productCardImages.value || []) + const selectedPriceSet = computed(() => new Set(selectedPriceOptions.value || [])) const selectedProductCodeSet = computed(() => new Set(selectedProductCodes.value || [])) const selectedCampaignLabelSet = computed(() => new Set(selectedCampaignLabels.value || [])) @@ -739,13 +851,84 @@ async function loadImagesForRows (list) { timeout: 15000 }) const first = Array.isArray(res?.data) ? res.data[0] : null - const url = toText(first?.thumb_url || first?.content_url || first?.full_url) + const url = resolveProductImageUrl(first) imageCache.set(key, url) row.imageUrl = url + imageListCache.set(key, Array.isArray(res?.data) ? res.data : []) } catch { imageCache.set(key, '') } })) + rows.value = [...rows.value] +} + +function normalizeUploadsPath (storagePath) { + const raw = toText(storagePath) + if (!raw) return '' + const normalized = raw.replace(/\\/g, '/') + const idx = normalized.toLowerCase().indexOf('/uploads/') + if (idx >= 0) return normalized.slice(idx) + if (normalized.toLowerCase().startsWith('uploads/')) return `/${normalized}` + return '' +} + +function resolveProductImageUrl (item) { + if (!item || typeof item !== 'object') return '' + const imageId = Number(item.id || item.ID || 0) + if (Number.isFinite(imageId) && imageId > 0) return `/api/product-images/${imageId}/content` + const thumbUrl = toText(item.thumb_url || item.thumbUrl) + if (thumbUrl) return thumbUrl + const fullUrl = toText(item.full_url || item.fullUrl) + if (fullUrl) return fullUrl + const contentUrl = toText(item.content_url || item.ContentURL) + if (contentUrl) return contentUrl.startsWith('/api/') ? contentUrl : contentUrl + const uploadsPath = normalizeUploadsPath(item.storage_path || item.storage) + if (uploadsPath) return uploadsPath + const fileName = toText(item.file_name || item.FileName) + return fileName ? `/uploads/image/${fileName}` : '' +} + +async function fetchImageListForRow (row) { + const key = `${row.productCode}|${row.dim1 || 0}|${row.dim3 || 0}` + if (imageListCache.has(key)) return imageListCache.get(key) || [] + const res = await api.get('/product-images', { + params: { + code: row.productCode, + dim1_id: row.dim1 || '', + dim3_id: row.dim3 || '' + }, + timeout: 15000 + }) + const list = Array.isArray(res?.data) ? res.data : [] + imageListCache.set(key, list) + return list +} + +async function openProductCard (row) { + if (!row) return + productCardData.value = { ...row } + productCardDialog.value = true + productCardSlide.value = 0 + try { + const list = await fetchImageListForRow(row) + const images = list.map(resolveProductImageUrl).filter(Boolean) + if (row.imageUrl && !images.includes(row.imageUrl)) images.unshift(row.imageUrl) + productCardImages.value = Array.from(new Set(images)) + } catch { + productCardImages.value = row.imageUrl ? [row.imageUrl] : [] + } +} + +function openProductImageFullscreen (src) { + const value = toText(src) + if (!value) return + const idx = Math.max(0, fullscreenImages.value.findIndex((x) => toText(x) === value)) + productImageFullscreenSlide.value = idx + productImageFullscreenDialog.value = true +} + +function onProductCardDialogHide () { + productImageFullscreenDialog.value = false } function resetSelections () { @@ -793,7 +976,7 @@ function col (name, label, field, width, extra = {}) { } const allColumns = [ - col('image', '', 'imageUrl', 58, { align: 'center', classes: 'image-col sticky-col' }), + col('image', '', 'imageUrl', 108, { align: 'center', classes: 'image-col sticky-col' }), col('brandGroupSelection', 'MARKA GRUBU', 'brandGroupSelection', 86, { classes: 'ps-col sticky-col' }), col('marka', 'MARKA', 'marka', 62, { sortable: true, classes: 'ps-col sticky-col' }), col('productCode', 'URUN KODU', 'productCode', 112, { sortable: true, classes: 'ps-col product-code-col sticky-col' }), @@ -801,9 +984,6 @@ const allColumns = [ col('variantStocks', 'STOK', 'stockQty', 62, { align: 'right', sortable: true, classes: 'ps-col variant-stock-col sticky-col' }), col('campaignLabel', 'KAMPANYA', 'campaignLabel', 150, { classes: 'ps-col campaign-col sticky-col' }), col('campaignRate', 'IND %', 'campaignRate', 58, { align: 'right', classes: 'ps-col campaign-rate-col sticky-col' }), - col('stockEntryDate', 'STOK GIRIS', 'stockEntryDate', 86, { align: 'center', sortable: true, classes: 'ps-col date-col' }), - col('lastPricingDate', 'SON FIYAT', 'lastPricingDate', 86, { align: 'center', sortable: true, classes: 'ps-col date-col' }), - col('lastCampaignDate', 'SON KAMPANYA', 'lastCampaignDate', 98, { align: 'center', sortable: true, classes: 'ps-col date-col' }), col('askiliYan', 'ASKILI YAN', 'askiliYan', 58, { sortable: true, classes: 'ps-col' }), col('kategori', 'KATEGORI', 'kategori', 58, { sortable: true, classes: 'ps-col' }), col('urunIlkGrubu', 'URUN ILK GRUBU', 'urunIlkGrubu', 70, { sortable: true, classes: 'ps-col' }), @@ -818,9 +998,6 @@ const allColumns = [ ] const hideableLeftDetailColumnNames = new Set([ - 'stockEntryDate', - 'lastPricingDate', - 'lastCampaignDate', 'askiliYan', 'kategori', 'urunIlkGrubu', @@ -906,7 +1083,7 @@ function exportCell (row, col) { function exportVisibleExcel () { const cols = visibleColumns.value const body = filteredRows.value.map((row) => `${cols.map((c) => { - if (c.name === 'image' && row.imageUrl) return `` + if (c.name === 'image' && row.imageUrl) return `` return `${escapeHtml(exportCell(row, c))}` }).join('')}`).join('') const html = `${cols.map((c) => ``).join('')}${body}
${escapeHtml(c.label || 'Gorsel')}
` @@ -935,7 +1112,7 @@ function printVisibleRows () { th { background: #957116; color: #fff; } th, td { border: 1px solid #ccc; padding: 3px; vertical-align: middle; } .num { text-align: right; } - .thumb { width: 42px; height: 42px; object-fit: cover; } + .thumb { width: 100px; height: 100px; object-fit: cover; }

Fiyat Listesi

${cols.map((c) => ``).join('')}${body}
${escapeHtml(c.label || 'Gorsel')}