fix(register): hide or require referral from settings like other apps
Also keep exact trade grams from rial and poll colleague wait every 10s. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
class=""
|
||||
@change="handlerChange"
|
||||
@input="handlerChange"
|
||||
@blur="emits('blur', $event)"
|
||||
@focus="emits('focus', $event)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -67,7 +69,7 @@ const addonTextColor = computed(() => props.addonTextColor)
|
||||
const props = withDefaults(defineProps<Prop>(), {
|
||||
isPassword: false
|
||||
})
|
||||
const emits = defineEmits(['update:value', 'onchange'])
|
||||
const emits = defineEmits(['update:value', 'onchange', 'blur', 'focus'])
|
||||
|
||||
const localValue = computed({
|
||||
set(value) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { getToken } from '@/utils'
|
||||
|
||||
export const colleagueOrderWaiting = ref(false)
|
||||
|
||||
const CLIENT_POLL_MS = 5000
|
||||
const CLIENT_POLL_MS = 10000
|
||||
const MAX_WAIT_MS = 15 * 60 * 1000
|
||||
const STREAM_EVENT = 'colleague-order'
|
||||
|
||||
|
||||
@@ -99,6 +99,16 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
const metalTypeLabel = computed(() => resolveMetalTypeLabel(metalTypeSettingValue.value))
|
||||
const meltedGoldLabel = computed(() => resolveMeltedGoldLabel(metalTypeSettingValue.value))
|
||||
const tradeWeightUnit = computed(() => resolveTradeWeightUnit(getSettingByKey('unit')))
|
||||
const isReferralFieldVisible = computed(() => {
|
||||
if (!settings.value?.some((s) => s?.key === 'referral_show')) return true
|
||||
return isSettingTruthy('referral_show')
|
||||
})
|
||||
|
||||
const isReferralRequired = computed(() => {
|
||||
if (!isReferralFieldVisible.value) return false
|
||||
const value = String(getSettingByKey('referral_id') ?? '').trim().toLowerCase()
|
||||
return value === 'required' || value === 'true' || value === '1' || value === 'yes'
|
||||
})
|
||||
|
||||
return {
|
||||
settings,
|
||||
@@ -108,6 +118,8 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
mergeSettings,
|
||||
getSettingByKey,
|
||||
isSettingTruthy,
|
||||
isReferralRequired,
|
||||
isReferralFieldVisible,
|
||||
metalTypeSettingValue,
|
||||
metalTypeLabel,
|
||||
meltedGoldLabel,
|
||||
|
||||
+52
-6
@@ -25,9 +25,12 @@ export const TRADE_GRAM_STORAGE_DECIMALS = 10
|
||||
/** حداکثر اعشار نمایش به کاربر در اپ */
|
||||
export const TRADE_GRAM_DISPLAY_DECIMALS = 8
|
||||
|
||||
/** اعشار فیلد گرم وقتی از ریال تبدیل میشود (فقط نمایش همان فیلد) */
|
||||
/** اعشار فیلد گرم وقتی از ریال تبدیل میشود (فقط نمایش همان فیلد؛ مقدار دقیق جداست) */
|
||||
export const TRADE_GRAM_INPUT_DECIMALS = 3
|
||||
|
||||
/** حداکثر اعشاری که کاربر میتواند در فیلد گرم تایپ کند */
|
||||
export const TRADE_GRAM_TYPING_DECIMALS = 6
|
||||
|
||||
/** زیر این مقدار (گرم)، معادل گرم در فیلد ورودی نشان داده نمیشود */
|
||||
export const TRADE_GRAM_MIN_DISPLAY_GRAMS = 0.0001
|
||||
|
||||
@@ -65,7 +68,7 @@ export function formatTradeGramInputValue(grams?: number | null): string | undef
|
||||
return value.toFixed(TRADE_GRAM_INPUT_DECIMALS)
|
||||
}
|
||||
|
||||
/** متن اینپوت گرم — فقط نمایش سهرقمی؛ منبع حقیقت همان گرم دقیق است */
|
||||
/** متن اینپوت گرم وقتی مقدار از ریال آمده — فقط نمایش سهرقمی؛ منبع حقیقت همان گرم دقیق است */
|
||||
export function tradeGramInputDisplay(exactGrams?: number | string | null): string {
|
||||
if (exactGrams === undefined || exactGrams === null || exactGrams === '') return ''
|
||||
const n = Number(exactGrams)
|
||||
@@ -73,6 +76,43 @@ export function tradeGramInputDisplay(exactGrams?: number | string | null): stri
|
||||
return formatTradeGramInputValue(n) ?? ''
|
||||
}
|
||||
|
||||
/** متن اینپوت گرم وقتی خود کاربر وزن زده — تا ۶ رقم، بدون پد اجباری */
|
||||
export function tradeGramTypedDisplay(exactGrams?: number | string | null): string {
|
||||
if (exactGrams === undefined || exactGrams === null || exactGrams === '') return ''
|
||||
const n = Number(exactGrams)
|
||||
if (!Number.isFinite(n) || n <= 0) return ''
|
||||
return trimTrailingDecimalZeros(n.toFixed(TRADE_GRAM_TYPING_DECIMALS))
|
||||
}
|
||||
|
||||
export function tradeGramFieldText(
|
||||
exactGrams: number | string | null | undefined,
|
||||
inputLock: TradeInputLock,
|
||||
draft: string | null,
|
||||
): string {
|
||||
if (draft !== null) return draft
|
||||
if (inputLock === 'rial') return tradeGramInputDisplay(exactGrams)
|
||||
return tradeGramTypedDisplay(exactGrams)
|
||||
}
|
||||
|
||||
/** هنگام تایپ در فیلد گرم: حداکثر شش رقم اعشار؛ نقطهٔ انتهایی برای «۱۲.» نگه داشته میشود */
|
||||
export function sanitizeTradeGramTypingText(raw: unknown): string {
|
||||
const text = String(raw ?? '')
|
||||
if (text === '') return ''
|
||||
const firstDot = text.indexOf('.')
|
||||
if (firstDot === -1) return text
|
||||
const intPart = text.slice(0, firstDot)
|
||||
const decRaw = text.slice(firstDot + 1).replace(/\./g, '')
|
||||
if (decRaw === '') return `${intPart}.`
|
||||
return `${intPart}.${decRaw.slice(0, TRADE_GRAM_TYPING_DECIMALS)}`
|
||||
}
|
||||
|
||||
/** متن شروع ویرایش وقتی فیلد از روی ریال پر شده (۱.۰۰۰ → ۱) */
|
||||
export function tradeGramInputEditText(exactGrams?: number | string | null): string {
|
||||
const shown = tradeGramInputDisplay(exactGrams)
|
||||
if (!shown) return ''
|
||||
return shown.replace(/\.?0+$/, '')
|
||||
}
|
||||
|
||||
/** گرم دقیق از درصد کیف — بدون رند نمایشی اینپوت */
|
||||
export function exactGoldFromWalletPercent(balance: number, percent: number): number {
|
||||
if (!(Number(percent) > 0) || !(Number(balance) > 0)) return 0
|
||||
@@ -88,15 +128,21 @@ export function goldFromGramInputDisplay(
|
||||
exactGrams?: number | string | null
|
||||
): number | undefined {
|
||||
if (raw === '' || raw == null) return undefined
|
||||
const text = String(raw).trim()
|
||||
if (text === '') return undefined
|
||||
const typed = Number(text)
|
||||
const text = sanitizeTradeGramTypingText(raw).trim()
|
||||
if (text === '' || text === '.') return undefined
|
||||
const forNumber = text.endsWith('.') ? text.slice(0, -1) : text
|
||||
if (forNumber === '') return undefined
|
||||
const typed = Number(forNumber)
|
||||
if (!Number.isFinite(typed) || typed <= 0) return undefined
|
||||
|
||||
const exact = Number(exactGrams)
|
||||
if (Number.isFinite(exact) && exact > 0) {
|
||||
const shown = formatTradeGramInputValue(exact)
|
||||
if (shown != null && text === shown) {
|
||||
const typedShown = tradeGramTypedDisplay(exact)
|
||||
if (
|
||||
(shown != null && (text === shown || text === shown.replace(/\.?0+$/, ''))) ||
|
||||
text === typedShown
|
||||
) {
|
||||
return normalizeOrderGoldAmount(exact)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<BasicInput v-model:value="goldValueInput" :addon-before="weightUnit" :addon-bg-color="colors.primary"
|
||||
addon-text-color="white"
|
||||
:place-holder="amountFieldLabel"
|
||||
size="large" type="text" inputmode="decimal" />
|
||||
size="large" type="text" inputmode="decimal" @focus="startGramDraft" @blur="commitGramDraft" />
|
||||
</a-form-item>
|
||||
<div v-if="cashValidationMessage" class="text-red-700 text-xs font-bold mt-2">
|
||||
{{ cashValidationMessage }}
|
||||
@@ -289,7 +289,10 @@ import {
|
||||
calcTradeTargetCash,
|
||||
buildTradeConfirmBreakdown,
|
||||
formatTradeGramDisplay,
|
||||
tradeGramInputDisplay,
|
||||
tradeGramFieldText,
|
||||
tradeGramTypedDisplay,
|
||||
sanitizeTradeGramTypingText,
|
||||
tradeGramInputEditText,
|
||||
exactGoldFromWalletPercent,
|
||||
goldFromGramInputDisplay,
|
||||
loadServiceFeeFromSettings,
|
||||
@@ -441,13 +444,36 @@ const displayTradeGoldAmount = computed(() =>
|
||||
formatTradeGramDisplay(orderGoldAmount.value)
|
||||
)
|
||||
|
||||
const gramInputDraft = ref<string | null>(null)
|
||||
|
||||
function commitGramDraft() {
|
||||
gramInputDraft.value = null
|
||||
}
|
||||
|
||||
function startGramDraft() {
|
||||
if (gramInputDraft.value !== null) return
|
||||
gramInputDraft.value = inputLock.value === 'rial'
|
||||
? tradeGramInputEditText(form.value.goldValue)
|
||||
: tradeGramTypedDisplay(form.value.goldValue)
|
||||
}
|
||||
|
||||
const goldValueInput = computed({
|
||||
get() {
|
||||
const display = tradeGramInputDisplay(form.value.goldValue)
|
||||
const display = tradeGramFieldText(form.value.goldValue, inputLock.value, gramInputDraft.value)
|
||||
return display === '' ? undefined : display
|
||||
},
|
||||
set(raw: string | number | null | undefined) {
|
||||
const next = goldFromGramInputDisplay(raw, form.value.goldValue)
|
||||
if (raw === '' || raw == null) {
|
||||
gramInputDraft.value = ''
|
||||
form.value.goldValue = undefined
|
||||
form.value.goldCash = undefined
|
||||
form.value.percentWallet = 0
|
||||
inputLock.value = null
|
||||
return
|
||||
}
|
||||
const text = sanitizeTradeGramTypingText(raw)
|
||||
gramInputDraft.value = text
|
||||
const next = goldFromGramInputDisplay(text, form.value.goldValue)
|
||||
form.value.goldValue = next
|
||||
if (next == null) {
|
||||
form.value.goldCash = undefined
|
||||
@@ -645,6 +671,7 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
function percentChange(val: number) {
|
||||
commitGramDraft()
|
||||
if (val !== 0) {
|
||||
if (isBuy.value) {
|
||||
form.value.goldCash = unitCashCalculator.value * val
|
||||
@@ -711,6 +738,7 @@ function calculateCash(val: number) {
|
||||
}
|
||||
|
||||
function calculateGold(val: number) {
|
||||
commitGramDraft()
|
||||
inputLock.value = 'rial'
|
||||
const unit = unitPrice.value
|
||||
if (!unit || Number.isNaN(unit)) return
|
||||
@@ -748,6 +776,7 @@ function setIsBuy(val: boolean) {
|
||||
form.value.goldCash = undefined
|
||||
form.value.percentWallet = 0
|
||||
inputLock.value = null
|
||||
commitGramDraft()
|
||||
// console.log(bganim.value.classList)
|
||||
// bganim?.value?.classList.add(val?'right':'left')
|
||||
// bganim?.value?.style.transform = `translateX(${val ? '0' : '-100'});`
|
||||
|
||||
@@ -18,8 +18,18 @@
|
||||
<!-- <BasicInput v-model:value="userFormState.password" size="large" place-holder="کلمه عبور"/>-->
|
||||
<AInputPassword v-model:value="userFormState.password" place-holder="کلمه عبور" inputmode="decimal"/>
|
||||
</a-form-item>
|
||||
<a-form-item class="home_appear_fade_in_down" label="کد معرف" name="referral_id">
|
||||
<BasicInput :disabled="disableForm" v-model:value="userFormState.referral_id" place-holder="کد معرف"/>
|
||||
<a-form-item
|
||||
v-if="settingsStore.loaded && settingsStore.isReferralFieldVisible"
|
||||
:rules="referralIdRules"
|
||||
class="home_appear_fade_in_down"
|
||||
:label="referralIdPlaceholder"
|
||||
name="referral_id"
|
||||
>
|
||||
<BasicInput
|
||||
:disabled="disableForm"
|
||||
v-model:value="userFormState.referral_id"
|
||||
:place-holder="referralIdPlaceholder"
|
||||
/>
|
||||
</a-form-item>
|
||||
<!-- <a-form-item v-if="URLUserType() === 'customer'" :rules="[required()]" class="home_appear_fade_in_down"
|
||||
label="نام فروشگاه" name="shop_name">
|
||||
@@ -121,7 +131,7 @@ import type { User } from '@/models/login'
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import { loading, URLUserType } from '@/utils'
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import registerDelayImage from '@/assets/img/registerDelay.svg'
|
||||
@@ -129,8 +139,17 @@ import DialogVantOneButton from '@/components/DialogVantOneButton.vue'
|
||||
import { registerCustomer } from '@/api/login'
|
||||
import router from '@/router'
|
||||
import logo from "@/assets/img/logo_full_.png";
|
||||
import { useSettingsStore } from '@/store/settingsStore'
|
||||
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
const referralIdRules = computed(() =>
|
||||
settingsStore.isReferralRequired ? [required('کد معرف')] : [],
|
||||
)
|
||||
const referralIdPlaceholder = computed(() =>
|
||||
settingsStore.isReferralRequired ? 'کد معرف' : 'کد معرف (اختیاری)',
|
||||
)
|
||||
|
||||
// const stepTwoVerify = ref<boolean>(false)
|
||||
const registeredInfo = ref<boolean>(false)
|
||||
|
||||
@@ -148,13 +167,14 @@ async function handleOnComplete(value: string) {
|
||||
userFormState.token = value
|
||||
registerAccount()
|
||||
}*/
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
if (!settingsStore.loaded) {
|
||||
await settingsStore.fetchSettings()
|
||||
}
|
||||
if (router.currentRoute.value.query.id){
|
||||
userFormState.referral_id = router.currentRoute.value.query.id
|
||||
disableForm.value=true
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
|
||||
function registerAccount() {
|
||||
@@ -166,7 +186,11 @@ function registerAccount() {
|
||||
// if (!stepTwoVerify.value) {
|
||||
URLUserType() === 'single' ? userFormState.type = 2 : userFormState.type = 1
|
||||
// console.log(userFormState)
|
||||
if (!userFormState.referral_id || userFormState.referral_id === '') delete userFormState.referral_id
|
||||
if (!settingsStore.isReferralFieldVisible && !disableForm.value) {
|
||||
delete userFormState.referral_id
|
||||
} else if (!userFormState.referral_id || userFormState.referral_id === '') {
|
||||
delete userFormState.referral_id
|
||||
}
|
||||
const { id } = await registerCustomer(userFormState)
|
||||
registeredInfo.value = true
|
||||
// console.log(registeredInfo.value)
|
||||
|
||||
Reference in New Issue
Block a user