From a41dd6ef9e197a4fb73e51398ab40c539255b8b3 Mon Sep 17 00:00:00 2001 From: mohammad sedighi Date: Thu, 2 Jul 2026 00:34:07 +0330 Subject: [PATCH] fix sql --- src/components/BasicPacks/BasicInput.vue | 7 ++- src/utils/inputRules.ts | 46 ++++++++++++------- src/utils/persianDigits.ts | 26 ++++++++++- .../base/user/components/UserProfileForm.vue | 3 +- .../base/user/composables/useUserPage.ts | 3 ++ src/views/login/components/Login.vue | 12 ++++- src/views/login/components/PhoneVerify.vue | 2 +- src/views/login/components/Register.vue | 6 ++- src/views/login/composables/useLoginForm.ts | 5 ++ .../login/composables/useRegisterForm.ts | 2 + .../desktop/components/DesktopLoginForm.vue | 3 +- .../components/DesktopRegisterForm.vue | 4 +- 12 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/components/BasicPacks/BasicInput.vue b/src/components/BasicPacks/BasicInput.vue index 3afadee..f2aac0a 100644 --- a/src/components/BasicPacks/BasicInput.vue +++ b/src/components/BasicPacks/BasicInput.vue @@ -13,6 +13,7 @@ :size="props.size" :type="props.type" class="" + @input="handlerChange" @change="handlerChange" /> @@ -89,8 +91,9 @@ function normalizeValue(value: unknown) { return normalized } -const handlerChange = (e: any) => { - const normalized = normalizeValue(e.target.value) +const handlerChange = (e: Event | string) => { + const raw = typeof e === 'string' ? e : (e.target as HTMLInputElement | null)?.value + const normalized = normalizeValue(raw) emits('update:value', normalized) emits('onchange', normalized) } diff --git a/src/utils/inputRules.ts b/src/utils/inputRules.ts index ecd5fb5..c2770f4 100644 --- a/src/utils/inputRules.ts +++ b/src/utils/inputRules.ts @@ -38,6 +38,7 @@ import { persianToEnglishDigits } from '@/utils/persianDigits' export const mobileValidation = (title?: string): Rule => { const label = title ?? 'شماره تلفن' return { + transform: (value) => persianToEnglishDigits(String(value ?? '').trim()), validator: (_rule, value) => { const normalized = persianToEnglishDigits(String(value ?? '').trim()) if (!normalized) { @@ -94,14 +95,20 @@ const isValidNationalCode = (code) => { return +chars[9] === lastDigit } export const requireNationalCode = (code?: string) => { - return {required: true, validator: validateNCode, trigger: 'change'} + return { + required: true, + transform: (value) => persianToEnglishDigits(String(value ?? '').trim()), + validator: validateNCode, + trigger: 'change', + } } async function validateNCode(rule: Rule, value: any) { - if (!value) { + const normalized = persianToEnglishDigits(String(value ?? '').trim()) + if (!normalized) { return Promise.reject('وارد کردن کد ملی الزامیست') } - if (isValidNationalCode(value)) return Promise.resolve() + if (isValidNationalCode(normalized)) return Promise.resolve() else return Promise.reject('کد ملی وارد شده نامعتبر است') } @@ -153,13 +160,16 @@ let isBuyP=true let NumP=0 let groupTypeP: string | undefined let meltedBalanceP = 0 -const checkNumber = async (_rule: Rule, value: number) => { - - - if (!value) { +const checkNumber = async (_rule: Rule, value: number | string) => { + const normalizedRaw = persianToEnglishDigits(String(value ?? '').trim()) + if (!normalizedRaw) { return Promise.reject('تعداد محصول را مشخص کنید'); } - if (value % 1 !== 0) { + const numericValue = Number(normalizedRaw) + if (!Number.isFinite(numericValue)) { + return Promise.reject('تعداد محصول را مشخص کنید'); + } + if (numericValue % 1 !== 0) { return Promise.reject('استفاده از اعداد اعشاری مجاز نمی باشد') } if (isBuyP){ @@ -170,14 +180,14 @@ if (isBuyP){ if (!meltedBalanceP && isMainMetalWalletDealMethod(methodP)){ return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP)) } - if (priceP * value > availableCash && isCashLikeDealMethod(methodP)) + if (priceP * numericValue > availableCash && isCashLikeDealMethod(methodP)) return Promise.reject(getInsufficientCashWalletMessage(groupTypeP)) - if (amountP * value > meltedBalanceP && isMainMetalWalletDealMethod(methodP)) + if (amountP * numericValue > meltedBalanceP && isMainMetalWalletDealMethod(methodP)) return Promise.reject(getInsufficientGoldWalletMessage(groupTypeP, methodP)) else return Promise.resolve(); }else { - if (value > NumP) + if (numericValue > NumP) return Promise.reject('موجودی محصول ناکافی است') else return Promise.resolve(); @@ -200,6 +210,7 @@ export const justNumber2 = ( meltedBalanceP = meltedBalance ?? 0 return { required: true, + transform: (value) => persianToEnglishDigits(String(value ?? '').trim()), validator: checkNumber, trigger: 'change' } @@ -211,6 +222,7 @@ export const justNumber3 = (price: number, Num?:number ,isBuy?:boolean) => { isBuyP=isBuy return { required: true, + transform: (value) => persianToEnglishDigits(String(value ?? '').trim()), validator: checkNumber, trigger: 'change' } @@ -233,14 +245,16 @@ export const guideTypePassword = ref<{}>({ export const passwordRules = () => { return [ { + transform: (value) => persianToEnglishDigits(String(value ?? '')), validator: (rule: Rule, value: any) => { - if (value.length < 6) { + const normalized = persianToEnglishDigits(String(value ?? '')) + if (normalized.length < 6) { return Promise.reject('رمز عبور حداقل 6 رقم') } - const lengthCriteria = value.length >= 8 - const letterCriteria = /[A-Za-z]/.test(value) - const numberCriteria = /\d/.test(value) - const specialCharacterCriteria = /[@$!%*#?&]/.test(value) + const lengthCriteria = normalized.length >= 8 + const letterCriteria = /[A-Za-z]/.test(normalized) + const numberCriteria = /\d/.test(normalized) + const specialCharacterCriteria = /[@$!%*#?&]/.test(normalized) const criteriaMet = [ lengthCriteria, letterCriteria, diff --git a/src/utils/persianDigits.ts b/src/utils/persianDigits.ts index fc8976f..1143681 100644 --- a/src/utils/persianDigits.ts +++ b/src/utils/persianDigits.ts @@ -19,11 +19,33 @@ export function shouldNormalizeInputDigits(options: { inputmode?: string }): boolean { if (options.isPassword) { - return false + return true } - if (options.type === 'price' || options.type === 'number') { + const type = String(options.type ?? '').trim().toLowerCase() + if (type === 'price' || type === 'number' || type === 'tel') { return true } const mode = String(options.inputmode ?? '').trim().toLowerCase() return mode === 'numeric' || mode === 'decimal' || mode === 'number' } + +/** تبدیل ارقام فارسی/عربی در فیلدهای عددی فرم‌های احراز هویت و پروفایل */ +export function normalizeAuthFormFields(fields: { + mobile?: string | null + password?: string | null + token?: string | null + n_code?: string | number | null +}) { + if (fields.mobile != null && fields.mobile !== '') { + fields.mobile = persianToEnglishDigits(String(fields.mobile).trim()) + } + if (fields.password != null && fields.password !== '') { + fields.password = persianToEnglishDigits(String(fields.password)) + } + if (fields.token != null && fields.token !== '') { + fields.token = persianToEnglishDigits(String(fields.token).trim()) + } + if (fields.n_code != null && fields.n_code !== '') { + fields.n_code = persianToEnglishDigits(String(fields.n_code).trim()) + } +} diff --git a/src/views/base/user/components/UserProfileForm.vue b/src/views/base/user/components/UserProfileForm.vue index d433e0a..932de64 100644 --- a/src/views/base/user/components/UserProfileForm.vue +++ b/src/views/base/user/components/UserProfileForm.vue @@ -19,7 +19,8 @@ diff --git a/src/views/base/user/composables/useUserPage.ts b/src/views/base/user/composables/useUserPage.ts index 36df022..049af4b 100644 --- a/src/views/base/user/composables/useUserPage.ts +++ b/src/views/base/user/composables/useUserPage.ts @@ -16,6 +16,7 @@ import { getUserAvatarUrl } from '@/utils/file' import { useConfigStore } from '@/store/configStore' import { getConfigApp, isBoursecuProject, getBoursecuActionIconSrc } from '@/utils/config' import { getReferralShareText, getReferralShareTitle, shareReferralText } from '@/utils/referralShare' +import { normalizeAuthFormFields } from '@/utils/persianDigits' export interface UserMenuAction { id: string @@ -207,6 +208,7 @@ export function useUserPage() { formRef.value?.validateFields().then(async () => { try { loading.value = true + normalizeAuthFormFields(userFormState.value) await updateMe(userFormState.value) await userStore.getMyInfo() localAvatarUrl.value = getUserAvatarUrl(userStore.userInfo) @@ -224,6 +226,7 @@ export function useUserPage() { formPassRef.value?.validateFields().then(async () => { try { loading.value = true + normalizeAuthFormFields(userPassForm.value) await updatePass(userPassForm.value) await userStore.getMyInfo() editPassVisible.value = false diff --git a/src/views/login/components/Login.vue b/src/views/login/components/Login.vue index 68f3a05..8c71b7e 100644 --- a/src/views/login/components/Login.vue +++ b/src/views/login/components/Login.vue @@ -103,7 +103,12 @@ - +
@@ -387,6 +392,7 @@ import { isTWA } from "@/utils/config"; import BasicActionSheet from "@/components/BasicPacks/BasicActionSheet.vue"; +import { normalizeAuthFormFields } from '@/utils/persianDigits' import {getConfig} from "@/api/config"; import shareAppleIcon from '@/assets/img/share-apple.png' import addToHomeScreenIcon from '@/assets/img/Add-to-homeScreen.png' @@ -433,6 +439,7 @@ async function reSendCode() { userFormState.token = undefined // refOtpInput.value?.clearInput() enableSendAgainCode.value = false + normalizeAuthFormFields(userFormState) await loginCustomer(userFormState) reset() } @@ -472,11 +479,13 @@ function useStyle() { function handleOnChange(value: string) { userFormState.token = value + normalizeAuthFormFields(userFormState) // formRef.value?.validateFields() } async function handleOnComplete(value: string) { userFormState.token = value + normalizeAuthFormFields(userFormState) phoneVerification() } @@ -501,6 +510,7 @@ function phoneVerification() { formRef.value?.validateFields().then(async () => { try { loading.value = true + normalizeAuthFormFields(userFormState) if (isSMS.value) { if (!stepTwoVerify.value) { userFormState.token = undefined diff --git a/src/views/login/components/PhoneVerify.vue b/src/views/login/components/PhoneVerify.vue index a53deab..f860a59 100644 --- a/src/views/login/components/PhoneVerify.vue +++ b/src/views/login/components/PhoneVerify.vue @@ -3,7 +3,7 @@
ورود / ثبت نام
- +
مالکیت شماره باید به نام خودتان باشد
diff --git a/src/views/login/components/Register.vue b/src/views/login/components/Register.vue index 37d0d65..e05ece7 100644 --- a/src/views/login/components/Register.vue +++ b/src/views/login/components/Register.vue @@ -64,6 +64,7 @@ v-model:value="userFormState.mobile" :place-holder="variant === 'desktop' ? '۰۹۱۲۳۴۵۶۷۸۹' : 'شماره تلفن'" :size="variant === 'desktop' ? 'large' : undefined" + type="tel" inputmode="numeric" /> @@ -73,8 +74,9 @@ label="کلمه عبور" name="password" > - @@ -236,6 +238,7 @@ import router from '@/router' import {useConfigStore} from "@/store/configStore"; import {useSettingsStore} from '@/store/settingsStore' import {getProjectLoginLogo, getProjectLoginTaglineLines, hasCustomLoginLogoLayout} from "@/utils/config"; +import { normalizeAuthFormFields } from '@/utils/persianDigits' withDefaults( defineProps<{ @@ -288,6 +291,7 @@ function registerAccount() { URLUserType() === 'single' ? userFormState.type = 2 : userFormState.type = 1 // console.log(userFormState) if (!userFormState.referral_id || userFormState.referral_id === '') delete userFormState.referral_id + normalizeAuthFormFields(userFormState) const { id } = await registerCustomer(userFormState) registeredInfo.value = true // console.log(registeredInfo.value) diff --git a/src/views/login/composables/useLoginForm.ts b/src/views/login/composables/useLoginForm.ts index bc7ab0c..a8017cc 100644 --- a/src/views/login/composables/useLoginForm.ts +++ b/src/views/login/composables/useLoginForm.ts @@ -17,6 +17,7 @@ import { useWalletStore } from '@/store/walletStore' import { useSettingsStore } from '@/store/settingsStore' import { setTruth } from '@/app/authBoot' import { completeLoginNavigation } from '@/layouts/composables/useMobileScrollReset' +import { normalizeAuthFormFields } from '@/utils/persianDigits' export function useLoginForm() { const { time, onFinish, reset } = useCountdownTimer('00:02:00', 'mm:ss') @@ -41,6 +42,7 @@ export function useLoginForm() { async function reSendCode() { userFormState.token = undefined enableSendAgainCode.value = false + normalizeAuthFormFields(userFormState) await loginCustomer(userFormState) reset() } @@ -64,10 +66,12 @@ export function useLoginForm() { function handleOnChange(value: string) { userFormState.token = value + normalizeAuthFormFields(userFormState) } async function handleOnComplete(value: string) { userFormState.token = value + normalizeAuthFormFields(userFormState) phoneVerification() } @@ -103,6 +107,7 @@ export function useLoginForm() { formRef.value?.validateFields().then(async () => { try { loading.value = true + normalizeAuthFormFields(userFormState) if (isSMS.value) { if (!stepTwoVerify.value) { userFormState.token = undefined diff --git a/src/views/login/composables/useRegisterForm.ts b/src/views/login/composables/useRegisterForm.ts index 464ed8e..ce3410e 100644 --- a/src/views/login/composables/useRegisterForm.ts +++ b/src/views/login/composables/useRegisterForm.ts @@ -5,6 +5,7 @@ import type { User } from '@/models/login' import { loading, URLUserType } from '@/utils' import { registerCustomer } from '@/api/login' import router from '@/router' +import { normalizeAuthFormFields } from '@/utils/persianDigits' export function useRegisterForm() { const registeredInfo = ref(false) @@ -31,6 +32,7 @@ export function useRegisterForm() { if (!userFormState.referral_id || userFormState.referral_id === '') { delete userFormState.referral_id } + normalizeAuthFormFields(userFormState) await registerCustomer(userFormState) registeredInfo.value = true } catch (e: any) { diff --git a/src/views/login/desktop/components/DesktopLoginForm.vue b/src/views/login/desktop/components/DesktopLoginForm.vue index de04fdb..1444d82 100644 --- a/src/views/login/desktop/components/DesktopLoginForm.vue +++ b/src/views/login/desktop/components/DesktopLoginForm.vue @@ -107,8 +107,9 @@ function goToAboutUs() { label="کلمه عبور" name="password" > - diff --git a/src/views/login/desktop/components/DesktopRegisterForm.vue b/src/views/login/desktop/components/DesktopRegisterForm.vue index cbdd135..1274d6c 100644 --- a/src/views/login/desktop/components/DesktopRegisterForm.vue +++ b/src/views/login/desktop/components/DesktopRegisterForm.vue @@ -82,13 +82,15 @@ function handleSuccessDismiss() { v-model:value="userFormState.mobile" place-holder="۰۹۱۲۳۴۵۶۷۸۹" size="large" + type="tel" inputmode="numeric" /> -