From da5b113406268f8ca332e930e61de3440f0690aa Mon Sep 17 00:00:00 2001 From: adonis Date: Thu, 27 Aug 2026 14:37:39 +0330 Subject: [PATCH] fix moshtari code --- src/api/appBanners.ts | 68 +++++++++++-------- src/composables/useAppBannersAdmin.ts | 1 + src/model/appBanners.ts | 37 ++++++++++ .../customers/base/components/table.vue | 14 +++- .../customers/base/hooks/customerColumns.tsx | 27 ++++++-- 5 files changed, 108 insertions(+), 39 deletions(-) diff --git a/src/api/appBanners.ts b/src/api/appBanners.ts index 489633a..f95e8fd 100644 --- a/src/api/appBanners.ts +++ b/src/api/appBanners.ts @@ -6,6 +6,8 @@ import { LEGACY_SLIDER_BANNERS_CONST_KEY, LEGACY_THEME_BANNERS_CONST_KEY, emptyAppBanners, + isThemeBannersEmpty, + mergeAppBannersFromLegacy, parseAppBanners, serializeAppBanners, type AppBannersValue, @@ -51,6 +53,8 @@ export type AppBannersConstState = { /** فقط وقتی رکورد واقعاً با key=app_banners است؛ وگرنه null تا create شود */ id: number | null data: AppBannersValue + /** از settings_profile_banners پر شده — بهتر است یک‌بار ذخیره شود */ + healedFromLegacy?: boolean } async function loadLegacySliderInto(merged: AppBannersValue): Promise { @@ -67,9 +71,22 @@ async function loadLegacySliderInto(merged: AppBannersValue): Promise { } } +async function loadLegacyThemeBanners(): Promise { + try { + const themeRes = await useAxios.get( + `/api/const/key/${LEGACY_THEME_BANNERS_CONST_KEY}` + ) + const themeRow = pickConstRow(themeRes) + if (!themeRow) return emptyAppBanners() + return parseAppBanners(themeRow.value) + } catch { + return emptyAppBanners() + } +} + /** * یک API واحد برای همهٔ بنرها. - * اگر `app_banners` نبود یا اسلایدر خالی بود، از کلیدهای قدیمی migrate می‌کند (فقط خواندن). + * اگر `app_banners` نبود یا اسلات‌های تم خالی بود، از settings_profile_banners پر می‌کند. */ export async function loadAppBannersConst(): Promise { let appRow: Const | null = null @@ -81,44 +98,36 @@ export async function loadAppBannersConst(): Promise { } if (appRow) { - const data = parseAppBanners(appRow.value) - // رکورد جدید خالی: اسلایدر را از header_banner پر کن - if (!data.slider.length) { - await loadLegacySliderInto(data) + let data = parseAppBanners(appRow.value) + let healedFromLegacy = false + + // رکورد پوچ app_banners روی URLهای واقعی legacy سایه نیندازد + if (isThemeBannersEmpty(data) || !data.slider.length) { + const before = serializeAppBanners(data) + if (isThemeBannersEmpty(data)) { + const legacyTheme = await loadLegacyThemeBanners() + data = mergeAppBannersFromLegacy(data, legacyTheme) + } + if (!data.slider.length) { + await loadLegacySliderInto(data) + } + healedFromLegacy = serializeAppBanners(data) !== before } + return { id: appRow.id ?? appRow.const_id ?? null, data, + healedFromLegacy, } } const merged = emptyAppBanners() - - try { - const themeRes = await useAxios.get( - `/api/const/key/${LEGACY_THEME_BANNERS_CONST_KEY}` - ) - const themeRow = pickConstRow(themeRes) - if (themeRow) { - const themes = parseAppBanners(themeRow.value) - Object.assign(merged, { - homeAsset: themes.homeAsset, - piggyCreate: themes.piggyCreate, - productsHero: themes.productsHero?.length ? themes.productsHero : merged.productsHero, - referral: themes.referral, - share: themes.share, - invite: themes.invite, - slider: themes.slider?.length ? themes.slider : merged.slider, - }) - } - } catch { - // ignore - } - + const legacyTheme = await loadLegacyThemeBanners() + Object.assign(merged, mergeAppBannersFromLegacy(merged, legacyTheme)) await loadLegacySliderInto(merged) - // id=null → اولین ذخیره، رکورد جدید با key=app_banners می‌سازد - return { id: null, data: merged } + const hasLegacy = !isThemeBannersEmpty(merged) || merged.slider.length > 0 + return { id: null, data: merged, healedFromLegacy: hasLegacy } } async function syncLegacySliderConst(slides: IBenefits[]): Promise { @@ -177,7 +186,6 @@ export async function saveAppBannersConst( nextId = created?.id ?? created?.const_id ?? null } - // اپ مشتری هنوز header_banner می‌خواند — اسلایدر را همگام نگه دار try { await syncLegacySliderConst(data.slider ?? []) } catch (error) { diff --git a/src/composables/useAppBannersAdmin.ts b/src/composables/useAppBannersAdmin.ts index ab26aa4..be1146f 100644 --- a/src/composables/useAppBannersAdmin.ts +++ b/src/composables/useAppBannersAdmin.ts @@ -82,6 +82,7 @@ async function load(force = false) { constId.value = res.id applyLoadedData(res.data) loaded.value = true + // عمداً auto-save نمی‌کنیم: URLهای legacy ممکن است ۴۰۴ باشند و app_banners را خراب کنند } catch (error) { if (rev !== localRevision) { return diff --git a/src/model/appBanners.ts b/src/model/appBanners.ts index 22eda82..67d7d2c 100644 --- a/src/model/appBanners.ts +++ b/src/model/appBanners.ts @@ -74,6 +74,43 @@ function pairHasImage(pair: ThemeImagePair): boolean { return Boolean(pair.light || pair.dark) } +/** همهٔ اسلات‌های تم خالی‌اند (رکورد app_banners پوچ که روی legacy سایه انداخته) */ +export function isThemeBannersEmpty(data: AppBannersValue): boolean { + return ( + !pairHasImage(data.homeAsset) && + !pairHasImage(data.piggyCreate) && + !(data.productsHero ?? []).some(pairHasImage) && + !pairHasImage(data.referral) && + !pairHasImage(data.share) && + !pairHasImage(data.invite) + ) +} + +function mergePair(primary: ThemeImagePair, legacy: ThemeImagePair): ThemeImagePair { + return { + light: primary.light || legacy.light, + dark: primary.dark || legacy.dark, + } +} + +/** اسلات خالی primary را از legacy پر می‌کند؛ اسلایدر/محصولات اگر آرایه خالی باشد از legacy می‌آید */ +export function mergeAppBannersFromLegacy( + primary: AppBannersValue, + legacy: AppBannersValue, +): AppBannersValue { + return { + slider: primary.slider.length ? primary.slider : legacy.slider, + homeAsset: mergePair(primary.homeAsset, legacy.homeAsset), + piggyCreate: mergePair(primary.piggyCreate, legacy.piggyCreate), + productsHero: (primary.productsHero ?? []).some(pairHasImage) + ? primary.productsHero + : legacy.productsHero ?? [], + referral: mergePair(primary.referral, legacy.referral), + share: mergePair(primary.share, legacy.share), + invite: mergePair(primary.invite, legacy.invite), + } +} + /** آرایهٔ جدید یا سه اسلات قدیمی productsHero1/2/3 */ export function normalizeProductsHero(parsed: Record): ThemeImagePair[] { if (Array.isArray(parsed.productsHero)) { diff --git a/src/pages/menuPages/customers/base/components/table.vue b/src/pages/menuPages/customers/base/components/table.vue index 50a7850..089b37a 100644 --- a/src/pages/menuPages/customers/base/components/table.vue +++ b/src/pages/menuPages/customers/base/components/table.vue @@ -239,7 +239,7 @@