feat(user): identity gate for wallet/gift card and custom nav icons

This commit is contained in:
2026-10-20 09:10:03 +03:30
parent 5e181fdae9
commit 7626453def
14 changed files with 104 additions and 3 deletions
@@ -6,6 +6,8 @@ import {
type CustomerGiftCardItem,
} from '@/api/giftCard'
import { message } from 'ant-design-vue'
import { useUserStore } from '@/store/userStore'
import { isCustomerIdentityVerified } from '@/utils/customerIdentity'
export interface GiftCardPageContext {
form: Ref<{ code: string }>
@@ -17,6 +19,7 @@ export interface GiftCardPageContext {
listLoading: Ref<boolean>
loadMyGiftCards: () => Promise<void>
fillCode: (code: string) => void
identityRequiredVisible: Ref<boolean>
}
export const GIFT_CARD_PAGE_CONTEXT_KEY: InjectionKey<GiftCardPageContext> =
@@ -29,6 +32,8 @@ export function useGiftCardPage() {
const available = ref<CustomerGiftCardItem[]>([])
const history = ref<CustomerGiftCardItem[]>([])
const listLoading = ref(false)
const identityRequiredVisible = ref(false)
const userStore = useUserStore()
const disableButton = computed(() => {
if (!loading.value) {
@@ -56,6 +61,10 @@ export function useGiftCardPage() {
}
async function registerGiftCard() {
if (!isCustomerIdentityVerified(userStore.userInfo?.is_legal)) {
identityRequiredVisible.value = true
return
}
const code = form.value.code.trim()
if (!code) return
@@ -94,6 +103,7 @@ export function useGiftCardPage() {
listLoading,
loadMyGiftCards,
fillCode,
identityRequiredVisible,
}
provide(GIFT_CARD_PAGE_CONTEXT_KEY, context)
+3 -1
View File
@@ -2,6 +2,7 @@
<div class="gift-card-page-root">
<DesktopGiftCardView v-show="isDesktop" />
<MobileGiftCardView v-show="!isDesktop" />
<IdentityRequiredDialog v-model:show="identityRequiredVisible" action="ثبت کد هدیه" />
</div>
</template>
@@ -10,10 +11,11 @@ import { useDesktopBreakpoint } from '@/layouts/composables/useAppLayout'
import { useGiftCardPage } from './composables/useGiftCardPage'
import DesktopGiftCardView from './desktop/DesktopGiftCardView.vue'
import MobileGiftCardView from './mobile/MobileGiftCardView.vue'
import IdentityRequiredDialog from '@/components/IdentityRequiredDialog.vue'
const isDesktop = useDesktopBreakpoint()
useGiftCardPage()
const { identityRequiredVisible } = useGiftCardPage()
</script>
<style scoped>
@@ -157,6 +157,7 @@ export function useUserPage() {
id: 'support',
label: 'پشتیبانی',
icon: 'vuesax-linear:messages-2',
iconSrc: getBoursecuActionIconSrc('support'),
onClick: () => router.push({ name: 'support' }),
visible: isUserSupportChatEnabled(),
badge: unreadSupportCount.value > 0 ? unreadSupportCount.value : undefined,
@@ -187,6 +188,7 @@ export function useUserPage() {
id: 'rules',
label: 'قوانین و مقررات',
icon: 'vuesax-linear:task',
iconSrc: getBoursecuActionIconSrc('rules'),
onClick: () => router.push({ name: 'rules' }),
visible: true,
},
@@ -11,6 +11,7 @@ import { useInfiniteScroll } from '@vueuse/core'
import { message } from 'ant-design-vue'
import type { Card } from '@/models/wallet'
import { useUserStore } from '@/store/userStore'
import { isCustomerIdentityVerified } from '@/utils/customerIdentity'
import { useConfigStore } from '@/store/configStore'
import {
getWalletDepositQuickAmountsRial,
@@ -37,6 +38,7 @@ export interface WalletPageContext {
showConfirmCode: Ref<boolean>
withdrawInfModal: Ref<boolean>
infoVisible: Ref<boolean>
identityRequiredVisible: Ref<boolean>
refOtpInput: Ref<InstanceType<typeof OtpInput> | null>
form: Ref<Transaction>
extraNote: Ref<string>
@@ -84,6 +86,13 @@ export function useWalletPage() {
const chargeAccountModal = ref(false)
const showConfirmCode = ref(false)
const withdrawInfModal = ref(false)
const identityRequiredVisible = ref(false)
function ensureIdentity(): boolean {
if (isCustomerIdentityVerified(userStore.userInfo?.is_legal)) return true
identityRequiredVisible.value = true
return false
}
const infoVisible = ref(false)
const refOtpInput = ref<InstanceType<typeof OtpInput> | null>(null)
const mobileDepositScrollEl = ref<HTMLElement | null>(null)
@@ -190,6 +199,7 @@ export function useWalletPage() {
}
async function ok() {
if (!ensureIdentity()) return
try {
if (form.value.value !== undefined) {
loading.value = true
@@ -211,6 +221,7 @@ export function useWalletPage() {
}
async function handleOnComplete(value: string) {
if (!ensureIdentity()) return
try {
infoVisible.value = true
showConfirmCode.value = false
@@ -268,6 +279,7 @@ export function useWalletPage() {
showConfirmCode,
withdrawInfModal,
infoVisible,
identityRequiredVisible,
refOtpInput,
form,
extraNote,
+4
View File
@@ -78,6 +78,8 @@
<SkeletonLoading v-model:show="infoVisible" />
<IdentityRequiredDialog v-model:show="identityRequiredVisible" action="واریز یا برداشت" />
<WalletDepositGuideModal
v-model:visible="chargeAccountModal"
:support-link="depositGuideSupportLink"
@@ -117,6 +119,7 @@ import MobileWalletView from './mobile/MobileWalletView.vue'
import SkeletonLoading from './components/SkeletonLoading.vue'
import WalletAddCardForm from './components/WalletAddCardForm.vue'
import WalletDepositGuideModal from './components/WalletDepositGuideModal.vue'
import IdentityRequiredDialog from '@/components/IdentityRequiredDialog.vue'
const isDesktop = useDesktopBreakpoint()
@@ -126,6 +129,7 @@ const {
showConfirmCode,
withdrawInfModal,
infoVisible,
identityRequiredVisible,
refOtpInput,
extraNote,
supportMessengerText,