From c3aaeaf91a24830b2a7aae22ad58f9446c58d039 Mon Sep 17 00:00:00 2001 From: MojtabaSoumi Date: Wed, 1 Jul 2026 18:16:12 +0330 Subject: [PATCH 1/2] 1405/04/10-fix bugs --- src/App.vue | 2 +- src/app/bootstrap.ts | 2 + src/app/setupRouter.ts | 8 + src/assets/css/main.less | 27 +- src/layouts/config/navigation.ts | 1 + src/layouts/mobile/MobileAppLayout.vue | 40 ++- src/layouts/mobile/MobileBottomNav.vue | 36 ++- src/layouts/mobile/MobileOverflowMenu.vue | 37 ++- src/layouts/mobile/mobile-layout.less | 44 +++- src/layouts/styles/mobile-frame.less | 59 +++++ src/router/index.ts | 16 +- src/utils/useDraggableFloatingButton.ts | 104 ++++++-- .../base/about/mobile/MobileAboutView.vue | 12 +- src/views/base/cart/mobile/MobileCartView.vue | 6 +- .../base/fund/composables/useFundPage.ts | 4 +- src/views/base/fund/index.vue | 2 +- src/views/base/fund/mobile/MobileFundView.vue | 83 +++++- .../base/giftCard/components/GiftCardForm.vue | 25 +- .../giftCard/mobile/MobileGiftCardView.vue | 56 ++-- src/views/base/gold/index.vue | 39 +-- src/views/base/home/index.vue | 50 ++-- .../physicalReceive/components/NewRequest.vue | 223 +--------------- .../components/RequestList.vue | 63 +---- src/views/base/physicalReceive/index.vue | 241 ++++-------------- .../base/priceTrigger/components/Item.vue | 212 ++++++++------- src/views/base/priceTrigger/index.vue | 202 ++------------- src/views/base/products/index.vue | 142 ++++++----- .../base/rules/mobile/MobileRulesView.vue | 12 +- .../mobile/MobileTransactionsView.vue | 61 +++-- .../base/user/composables/useUserPage.ts | 6 + src/views/base/user/mobile/MobileUserView.vue | 51 ++-- .../base/wallet/mobile/MobileWalletView.vue | 14 +- uno.config.ts | 3 +- 33 files changed, 832 insertions(+), 1051 deletions(-) diff --git a/src/App.vue b/src/App.vue index 08e3eea..2073315 100644 --- a/src/App.vue +++ b/src/App.vue @@ -155,7 +155,7 @@ const { } = useDraggableFloatingButton('ghatreh_support_button_position_v1', { width: 118, height: 42, - defaultBottomOffset: 100, + defaultBottomGap: 12, defaultRightOffset: 16, }) diff --git a/src/app/bootstrap.ts b/src/app/bootstrap.ts index 46ec19d..d36ec1a 100644 --- a/src/app/bootstrap.ts +++ b/src/app/bootstrap.ts @@ -6,6 +6,7 @@ import { createVueApp } from '@/app/createApp' import { setupRouterGuards } from '@/app/setupRouter' import { useSettingsStore } from '@/store/settingsStore' import { initPriceRealtimeChannel } from '@/utils/priceSocket' +import { initMobileScrollRestoration } from '@/layouts/composables/useMobileScrollReset' type BootWindow = Window & { __BOOT_TIMEOUT__?: number @@ -74,6 +75,7 @@ export async function bootstrapApp() { await withTimeout(settingsStore.fetchSettings(), 45000, 'Settings loading timeout') initPriceRealtimeChannel((key) => settingsStore.getSettingByKey(key)) + initMobileScrollRestoration() setupRouterGuards() app.mount('#app') diff --git a/src/app/setupRouter.ts b/src/app/setupRouter.ts index ed90f86..4f1fca1 100644 --- a/src/app/setupRouter.ts +++ b/src/app/setupRouter.ts @@ -13,6 +13,7 @@ import { setFingerTimeOut, setHasFingerPrint } from '@/app/authBoot' +import { recoverMobileViewportAfterAuth } from '@/layouts/composables/useMobileScrollReset' export function setupRouterGuards() { const userStore = useUserStore() @@ -115,5 +116,12 @@ export function setupRouterGuards() { } }) + router.afterEach((to, from) => { + if (document.documentElement.classList.contains('app-layout--desktop')) return + if (from.name === 'login') { + recoverMobileViewportAfterAuth() + } + }) + watch(currentRoute, async () => (userStore.userInfo ? '' : await start())) } diff --git a/src/assets/css/main.less b/src/assets/css/main.less index e3621cd..fd048d3 100644 --- a/src/assets/css/main.less +++ b/src/assets/css/main.less @@ -2,11 +2,13 @@ @import (less) './fonts.less'; @import (less) '../../layouts/styles/desktop-shell.less'; @import (less) '../../layouts/styles/mobile-frame.less'; +@import (less) '../../layouts/styles/mobile-page-common.less'; @import (less) '../../layouts/desktop/styles/desktop-page-common.less'; @import (less) '../../views/base/fund/desktop/styles/desktop-fund.less'; @import (less) '../../views/base/transactions/desktop/styles/desktop-transactions.less'; @import (less) '../../views/base/wallet/desktop/styles/desktop-wallet.less'; @import (less) '../../views/base/user/desktop/styles/desktop-user.less'; +@import (less) '../../views/base/priceTrigger/desktop/styles/desktop-price-trigger.less'; @import (less) '../../views/base/home/desktop/styles/desktop-home.less'; @import (less) '../../layouts/desktop/styles/desktop-inner-pages.less'; @@ -59,6 +61,21 @@ body { :root { color-scheme: only light; + --app-safe-top: env(safe-area-inset-top, 0px); + --app-safe-bottom: env(safe-area-inset-bottom, 0px); + --app-credit-bar-inner: 0px; + --app-home-header-offset: calc(4.25rem + var(--app-safe-top)); + --app-credit-footer-offset: var(--app-safe-bottom); + --app-nav-height: 80px; + --app-bottom-chrome-height: calc(var(--app-nav-height) + var(--app-safe-bottom)); + --app-add-card-height: 88px; + --wallet-card-dock-overlap: 52px; + --app-z-nav: 5000; + --app-z-wallet-dock: 4490; + --app-z-wallet-add-bar: 4510; + --app-z-action-sheet: 5200; + --app-z-dialog: 5300; + --app-z-modal: 5500; } .ant-form-item { @@ -83,13 +100,13 @@ body { opacity: 0; } -/*.van-action-sheet{ - z-index: 2001 !important; +.van-action-sheet{ + z-index: 5001 !important; } -.van-overlay{ - z-index: 2000 !important; -}*/ +//.van-overlay{ +// z-index: 2000 !important; +//} .color-transition { transition: color 0.3s ease; diff --git a/src/layouts/config/navigation.ts b/src/layouts/config/navigation.ts index 1b86cb7..51bc417 100644 --- a/src/layouts/config/navigation.ts +++ b/src/layouts/config/navigation.ts @@ -18,6 +18,7 @@ export const GUEST_PRIMARY_NAV: AppNavItem[] = [ /** منوی FAB موبایل + بخش فرعی سایدبار دسکتاپ — کاربر لاگین‌شده */ export const AUTH_SECONDARY_NAV: AppNavItem[] = [ + { id: 'notifyTrigger', routeName: 'notifyTrigger', label: 'هشدار قیمت', icon: 'vuesax-linear:bill' }, { id: 'buyProduct', routeName: 'buyProduct', label: 'فروشگاه', icon: 'vuesax-linear:coin' }, { id: 'fund', routeName: 'fund', label: 'دارایی ها', icon: 'vuesax-linear:archive-1' }, { id: 'user', routeName: 'user', label: 'حساب کاربری', icon: 'vuesax-linear:user' }, diff --git a/src/layouts/mobile/MobileAppLayout.vue b/src/layouts/mobile/MobileAppLayout.vue index cc433e3..fff6c96 100644 --- a/src/layouts/mobile/MobileAppLayout.vue +++ b/src/layouts/mobile/MobileAppLayout.vue @@ -1,5 +1,5 @@ diff --git a/src/layouts/mobile/MobileBottomNav.vue b/src/layouts/mobile/MobileBottomNav.vue index 29ada63..76655c3 100644 --- a/src/layouts/mobile/MobileBottomNav.vue +++ b/src/layouts/mobile/MobileBottomNav.vue @@ -3,10 +3,12 @@
@@ -21,10 +23,12 @@ @@ -61,3 +65,19 @@ const primaryItems = computed(() => getPrimaryNavItems(isToken())) const leftTabs = computed(() => primaryItems.value.slice(0, 2)) const rightTabs = computed(() => primaryItems.value.slice(2)) + + diff --git a/src/layouts/mobile/MobileOverflowMenu.vue b/src/layouts/mobile/MobileOverflowMenu.vue index 14eda1a..c0951a0 100644 --- a/src/layouts/mobile/MobileOverflowMenu.vue +++ b/src/layouts/mobile/MobileOverflowMenu.vue @@ -2,12 +2,12 @@
-
+
دریافت طلای فیزیکی
+ +
+ +
هشدار قیمت
+
+
خرید محصول
- -
- -
لیست دریافتی ها
-
-
+ + + + + + + + + + + * { + height: 100%; + max-height: 100%; + overflow: hidden; + } + + .app-dock-add-bar, + .wallet-card-slider { + box-sizing: border-box; + } + @media screen and (max-width: 425.98px) { body { display: block !important; @@ -8,6 +46,7 @@ html:not(.app-layout--desktop) { #app, .desktopConfig, + .app-main, .main-with-bottom-chrome, .main-with-bottom-chrome-inner { width: 100% !important; @@ -25,6 +64,16 @@ html:not(.app-layout--desktop) { margin: 0 !important; transform: none !important; } + + .app-dock-add-bar, + .wallet-card-slider { + width: 100% !important; + max-width: 100vw !important; + left: 0 !important; + right: 0 !important; + margin: 0 !important; + transform: none !important; + } } @media screen and (min-width: 426px) and (max-width: 767.98px) { @@ -47,5 +96,15 @@ html:not(.app-layout--desktop) { margin: 0 !important; transform: translateX(-50%) !important; } + + .app-dock-add-bar, + .wallet-card-slider { + width: 426px !important; + max-width: 426px !important; + left: 50% !important; + right: auto !important; + margin: 0 !important; + transform: translateX(-50%) !important; + } } } diff --git a/src/router/index.ts b/src/router/index.ts index 1e792c4..a34ff80 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -85,22 +85,12 @@ const router = createRouter({ name: 'address', component: () => import('@/views/base/address/index.vue') }, - /* { - path: 'physicalReceive', - name: 'physicalReceive', - component: () => import('@/views/base/physicalReceive/index.vue'), - },*/ - // { - // path: 'list', - // name: 'list', - // component: () => import('@/views/base/physicalReceive/components/RequestList.vue'), - // }, { path: 'physicalReceive', name: 'physicalReceive', - redirect:{name: 'list'}, - // component: () => import('@/views/base/physicalReceive/index.vue'), - children:[ + redirect: { name: 'list' }, + component: () => import('@/views/base/physicalReceive/index.vue'), + children: [ { path: '', name: 'list', diff --git a/src/utils/useDraggableFloatingButton.ts b/src/utils/useDraggableFloatingButton.ts index af3feb7..6f28c07 100644 --- a/src/utils/useDraggableFloatingButton.ts +++ b/src/utils/useDraggableFloatingButton.ts @@ -1,24 +1,53 @@ import { computed, onMounted, onUnmounted, ref } from 'vue' const DRAG_THRESHOLD = 6 +const POSITION_VERSION = 1 type FabPosition = { x: number; y: number } +type SavedFabOffset = { + version: number + dx: number + dy: number +} + type DraggableFloatingOptions = { width?: number height?: number - defaultBottomOffset?: number + defaultBottomGap?: number defaultRightOffset?: number } +function readBottomChromeHeight(): number { + const styles = getComputedStyle(document.documentElement) + const direct = parseFloat(styles.getPropertyValue('--app-bottom-chrome-height')) + if (!Number.isNaN(direct) && direct > 0) { + return direct + } + + const nav = parseFloat(styles.getPropertyValue('--app-nav-height')) || 80 + const creditOffset = parseFloat(styles.getPropertyValue('--app-credit-footer-offset')) + if (!Number.isNaN(creditOffset) && creditOffset > 0) { + return nav + creditOffset + } + + const probe = document.createElement('div') + probe.style.cssText = 'position:fixed;visibility:hidden;pointer-events:none;height:var(--app-bottom-chrome-height)' + document.body.appendChild(probe) + const measured = probe.getBoundingClientRect().height + document.body.removeChild(probe) + + return measured > 0 ? measured : nav +} + export function useDraggableFloatingButton( storageKey: string, options: DraggableFloatingOptions = {} ) { const width = options.width ?? 96 const height = options.height ?? 44 - const defaultBottomOffset = options.defaultBottomOffset ?? 92 - const defaultRightOffset = options.defaultRightOffset ?? 20 + const defaultBottomGap = options.defaultBottomGap ?? 12 + const defaultRightOffset = options.defaultRightOffset ?? 16 const pos = ref({ x: 0, y: 0 }) const dragging = ref(false) @@ -44,26 +73,40 @@ export function useDraggableFloatingButton( function getHorizontalOffset() { const vw = window.innerWidth const contentWidth = getViewportWidth() + return Math.max(0, (vw - contentWidth) / 2) } - function resetToDefault() { + function getDefaultPosition(): FabPosition { const vh = window.innerHeight const offsetX = getHorizontalOffset() const contentWidth = getViewportWidth() + const bottomChrome = readBottomChromeHeight() - pos.value = { + return { x: offsetX + contentWidth - width - defaultRightOffset, - y: vh - defaultBottomOffset - height + y: vh - bottomChrome - defaultBottomGap - height } } + function applySavedOffset(dx: number, dy: number) { + const base = getDefaultPosition() + pos.value = { + x: base.x + dx, + y: base.y + dy + } + clampToViewport() + } + function clampToViewport() { - const vw = window.innerWidth const vh = window.innerHeight + const offsetX = getHorizontalOffset() + const contentWidth = getViewportWidth() + const minX = offsetX + const maxX = offsetX + contentWidth - width pos.value = { - x: Math.max(0, Math.min(vw - width, pos.value.x)), + x: Math.max(minX, Math.min(maxX, pos.value.x)), y: Math.max(0, Math.min(vh - height, pos.value.y)) } } @@ -72,25 +115,56 @@ export function useDraggableFloatingButton( try { const raw = localStorage.getItem(storageKey) if (!raw) return false - const parsed = JSON.parse(raw) as FabPosition - if (typeof parsed?.x === 'number' && typeof parsed?.y === 'number') { - pos.value = parsed - clampToViewport() + + const parsed = JSON.parse(raw) as SavedFabOffset + if ( + parsed?.version === POSITION_VERSION + && typeof parsed.dx === 'number' + && typeof parsed.dy === 'number' + ) { + applySavedOffset(parsed.dx, parsed.dy) return true } } catch { // ignore } + return false } function savePosition() { - localStorage.setItem(storageKey, JSON.stringify(pos.value)) + const base = getDefaultPosition() + const payload: SavedFabOffset = { + version: POSITION_VERSION, + dx: pos.value.x - base.x, + dy: pos.value.y - base.y + } + localStorage.setItem(storageKey, JSON.stringify(payload)) + } + + function resetToDefault() { + pos.value = getDefaultPosition() } function handleResize() { - clampToViewport() - savePosition() + try { + const raw = localStorage.getItem(storageKey) + if (raw) { + const parsed = JSON.parse(raw) as SavedFabOffset + if ( + parsed?.version === POSITION_VERSION + && typeof parsed.dx === 'number' + && typeof parsed.dy === 'number' + ) { + applySavedOffset(parsed.dx, parsed.dy) + return + } + } + } catch { + // ignore + } + + resetToDefault() } function handlePointerDown(event: PointerEvent) { diff --git a/src/views/base/about/mobile/MobileAboutView.vue b/src/views/base/about/mobile/MobileAboutView.vue index c747a62..b386807 100644 --- a/src/views/base/about/mobile/MobileAboutView.vue +++ b/src/views/base/about/mobile/MobileAboutView.vue @@ -1,12 +1,7 @@ diff --git a/src/views/base/cart/mobile/MobileCartView.vue b/src/views/base/cart/mobile/MobileCartView.vue index 761d043..d12825e 100644 --- a/src/views/base/cart/mobile/MobileCartView.vue +++ b/src/views/base/cart/mobile/MobileCartView.vue @@ -1,8 +1,8 @@