diff --git a/.cursor/skills/abshode-domain-lookup/learned-notes.md b/.cursor/skills/abshode-domain-lookup/learned-notes.md index 9c88df0..2f690f6 100644 --- a/.cursor/skills/abshode-domain-lookup/learned-notes.md +++ b/.cursor/skills/abshode-domain-lookup/learned-notes.md @@ -3,6 +3,8 @@ فرمت هر خط: - YYYY-MM-DD | موضوع | مسیر فایل(ها) | نکتهٔ ۱ خطی +- 2026-10-19 | قفل احراز واریز/هدیه | `useWalletPage` + `useGiftCardPage` + `assertCustomerIdentityVerified` روی withdraw و giftcard/use | is_legal=0 دیالوگ می‌دهد و API هم رد می‌کند +- 2026-10-19 | آیکون پشتیبانی/هشدار/قوانین | `assets/img/boursecu-support-icon.png` + `price-trigger` + `rules` و `navigation.ts` / `useUserPage.ts` | آدمک=پشتیبانی، زنگ دلار=هشدار قیمت سایدبار، برگه=قوانین - 2026-09-08 | لیست کارت هدیه کاربر | `views/base/giftCard/` + `api/giftCard.ts` + سرور `GiftCardController::mine` / `GET customer/giftcard/mine` | زیر فرم: available (اختصاصی + عمومی use_once=0 تک‌کد) و history؛ تخفیف فقط نمایش/سبد نه giftcard/use - 2026-09-08 | تب کارت هدیه/تخفیف در تراکنش‌ها | `transactions/config/boursecuTabs.ts` + `useTransactionsPageData.ts` + `Item.vue` | fetchMode giftcard/discount از historyِ mine؛ واحد تخفیف٪/طلا در Item - 2026-09-08 | گیر کردن در لاگین بعد رفرش | `app/authBoot.ts` + `setupRouter.ts` | finger unlock در sessionStorage؛ بعد ۳دقیقه fingerprintChecked ریست؛ لاگین بدون userInfo نرود home diff --git a/components.d.ts b/components.d.ts index 99e0757..d4a22b5 100644 --- a/components.d.ts +++ b/components.d.ts @@ -56,6 +56,7 @@ declare module 'vue' { Format: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/format.vue')['default'] GoldDayCalculatorModal: typeof import('./src/components/GoldDayCalculatorModal.vue')['default'] GoldLoading: typeof import('./src/components/GoldLoading.vue')['default'] + IdentityRequiredDialog: typeof import('./src/components/IdentityRequiredDialog.vue')['default'] InstallButton: typeof import('./src/components/InstallButton.vue')['default'] ListAnim: typeof import('./src/components/ListAnim.vue')['default'] Mode: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/mode.vue')['default'] diff --git a/src/assets/img/boursecu-price-trigger-icon.png b/src/assets/img/boursecu-price-trigger-icon.png new file mode 100644 index 0000000..aeaca90 Binary files /dev/null and b/src/assets/img/boursecu-price-trigger-icon.png differ diff --git a/src/assets/img/boursecu-rules-icon.png b/src/assets/img/boursecu-rules-icon.png new file mode 100644 index 0000000..e595ba4 Binary files /dev/null and b/src/assets/img/boursecu-rules-icon.png differ diff --git a/src/assets/img/boursecu-support-icon.png b/src/assets/img/boursecu-support-icon.png new file mode 100644 index 0000000..df683d1 Binary files /dev/null and b/src/assets/img/boursecu-support-icon.png differ diff --git a/src/components/IdentityRequiredDialog.vue b/src/components/IdentityRequiredDialog.vue new file mode 100644 index 0000000..fa4258a --- /dev/null +++ b/src/components/IdentityRequiredDialog.vue @@ -0,0 +1,46 @@ + + + diff --git a/src/layouts/config/navigation.ts b/src/layouts/config/navigation.ts index b5b7a35..b8fb80c 100644 --- a/src/layouts/config/navigation.ts +++ b/src/layouts/config/navigation.ts @@ -57,9 +57,21 @@ const BOURSECU_PRIMARY_NAV: AppNavItem[] = [ ] export const SECONDARY_NAV: AppNavItem[] = [ - { id: 'notifyTrigger', routeName: 'notifyTrigger', label: 'هشدار قیمت', icon: 'vuesax-linear:bill' }, + { + id: 'notifyTrigger', + routeName: 'notifyTrigger', + label: 'هشدار قیمت', + icon: 'vuesax-linear:bill', + iconSrc: getBoursecuActionIconSrc('priceTrigger'), + }, { id: 'about', routeName: 'about', label: 'درباره ما', icon: 'vuesax-linear:info-circle' }, - { id: 'rules', routeName: 'rules', label: 'قوانین و مقررات', icon: 'vuesax-linear:task' }, + { + id: 'rules', + routeName: 'rules', + label: 'قوانین و مقررات', + icon: 'vuesax-linear:task', + iconSrc: getBoursecuActionIconSrc('rules'), + }, ] export function getPrimaryNavItems(): AppNavItem[] { diff --git a/src/utils/config.ts b/src/utils/config.ts index 2272a6a..5177e54 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -9,6 +9,9 @@ import boursecuBuySellIcon from '@/assets/img/boursecu-buy-sell-icon.png' import boursecuAssetsIcon from '@/assets/img/boursecu-assets-icon.png' import boursecuHomeIcon from '@/assets/img/boursecu-home-icon.png' import boursecuSettingsIcon from '@/assets/img/boursecu-settings-icon.png' +import boursecuSupportIcon from '@/assets/img/boursecu-support-icon.png' +import boursecuPriceTriggerIcon from '@/assets/img/boursecu-price-trigger-icon.png' +import boursecuRulesIcon from '@/assets/img/boursecu-rules-icon.png' export function getConfigApp(key: string) { const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user : {} @@ -77,6 +80,9 @@ export function getBoursecuActionIconSrc(actionId: string): string | undefined { convert: boursecuConvertIcon, home: boursecuHomeIcon, settings: boursecuSettingsIcon, + support: boursecuSupportIcon, + priceTrigger: boursecuPriceTriggerIcon, + rules: boursecuRulesIcon, } return icons[actionId] diff --git a/src/utils/customerIdentity.ts b/src/utils/customerIdentity.ts new file mode 100644 index 0000000..c397755 --- /dev/null +++ b/src/utils/customerIdentity.ts @@ -0,0 +1,4 @@ +/** احراز نشده = is_legal صفر. ۱ و ۲ یعنی اطلاعات ثبت شده و معامله مجاز است. */ +export function isCustomerIdentityVerified(isLegal: unknown): boolean { + return Number(isLegal ?? 0) !== 0 +} diff --git a/src/views/base/giftCard/composables/useGiftCardPage.ts b/src/views/base/giftCard/composables/useGiftCardPage.ts index d551202..817ce34 100644 --- a/src/views/base/giftCard/composables/useGiftCardPage.ts +++ b/src/views/base/giftCard/composables/useGiftCardPage.ts @@ -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 loadMyGiftCards: () => Promise fillCode: (code: string) => void + identityRequiredVisible: Ref } export const GIFT_CARD_PAGE_CONTEXT_KEY: InjectionKey = @@ -29,6 +32,8 @@ export function useGiftCardPage() { const available = ref([]) const history = ref([]) 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) diff --git a/src/views/base/giftCard/index.vue b/src/views/base/giftCard/index.vue index 25adcf0..fe99a48 100644 --- a/src/views/base/giftCard/index.vue +++ b/src/views/base/giftCard/index.vue @@ -2,6 +2,7 @@
+
@@ -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()