diff --git a/src/views/base/products/composables/useProductsPageData.ts b/src/views/base/products/composables/useProductsPageData.ts index e997ac2..43d2f74 100644 --- a/src/views/base/products/composables/useProductsPageData.ts +++ b/src/views/base/products/composables/useProductsPageData.ts @@ -35,24 +35,42 @@ function sortProductsByInventory(products: Product[]) { } export function changeProductsTab() { + const all = productsFirstItems.value if (productsActiveKey.value !== 'همه') { - productsItems.value = productsFirstItems.value?.filter( - (val) => val.group_type === productsActiveKey.value, - ) + const filtered = all?.filter((val) => val.group_type === productsActiveKey.value) + if (!filtered?.length) { + productsActiveKey.value = 'همه' + productsItems.value = all + return + } + productsItems.value = filtered } else { - productsItems.value = productsFirstItems.value + productsItems.value = all } } async function loadCategoryTabs() { try { productsTypeItems.value = await loadProductCategoryTabNames() + pruneEmptyTypeItems() } catch (error) { console.error('Product category tabs error:', error) productsTypeItems.value = [] } } +/** دسته‌ای که هیچ محصول فعالی ندارد از تب‌ها حذف شود */ +function pruneEmptyTypeItems() { + const products = productsFirstItems.value + if (!products?.length) { + return + } + const present = new Set( + products.map((p) => p.group_type).filter((key): key is string => !!key), + ) + productsTypeItems.value = productsTypeItems.value.filter((key) => present.has(key)) +} + function productFileId(product: Product): number { return Number(product.file_id ?? (product.file as { id?: number } | undefined)?.id ?? 0) } @@ -99,9 +117,57 @@ function mergeLiveProductList(incoming: Product[], current?: Product[]): Product }) } +/** فقط محصول فعال ادمین (باز) — نه show لحظه‌ای ساعت/مظنه */ +function isActiveProduct(product: Product): boolean { + const active = product.active as unknown + return active !== false && active !== 0 && active !== '0' +} + +/** استریم گاهی لیست ناقص می‌فرستد — عضوهای قبلی را دور نریز. */ +function mergeSocketProductMembership(incoming: Product[], current?: Product[]): Product[] { + if (!current?.length) return incoming + + const incomingById = new Map(incoming.map((item) => [item.id, item])) + const currentIds = new Set(current.map((item) => item.id)) + const hasAdded = incoming.some((item) => !currentIds.has(item.id)) + const missingFromIncoming = current.some((item) => !incomingById.has(item.id)) + + if (missingFromIncoming && !hasAdded && incoming.length < current.length) { + return current.map((item) => { + const updated = incomingById.get(item.id) + return updated ? { ...item, ...updated } : item + }) + } + + const merged = incoming.map((item) => { + const prev = current.find((row) => row.id === item.id) + return prev ? { ...prev, ...item } : item + }) + + if (missingFromIncoming) { + for (const item of current) { + if (!incomingById.has(item.id)) { + merged.push(item) + } + } + } + + return merged +} + function applyProductsList(products: Product[]) { - const sorted = sortProductsByInventory(products) + const visible = products.filter(isActiveProduct) + const sorted = sortProductsByInventory(visible) productsFirstItems.value = sorted + pruneEmptyTypeItems() + + if ( + productsActiveKey.value !== 'همه' && + !sorted.some((p) => p.group_type === productsActiveKey.value) + ) { + productsActiveKey.value = 'همه' + } + changeProductsTab() productsPageLoading.value = false } @@ -122,10 +188,12 @@ export function applyProductsListFromSocket(products: Product[]) { return } - const merged = mergeLiveProductList( - products, - getProductsCatalogRef().value.length ? getProductsCatalogRef().value : productsFirstItems.value, - ) + const base = + getProductsCatalogRef().value.length + ? getProductsCatalogRef().value + : productsFirstItems.value + const withImages = mergeLiveProductList(products, base) + const merged = mergeSocketProductMembership(withImages, base) getProductsCatalogRef().value = merged applyProductsList(merged) } diff --git a/src/views/base/products/index.vue b/src/views/base/products/index.vue index 2d0c0f6..df75560 100644 --- a/src/views/base/products/index.vue +++ b/src/views/base/products/index.vue @@ -19,7 +19,7 @@ > همه