fix price input

This commit is contained in:
2026-06-22 12:08:47 +03:30
parent c3abeeecef
commit cc5e3ce5f2
2 changed files with 49 additions and 16 deletions
@@ -32,13 +32,24 @@
</a-select>
<a-input-number
v-else-if="fieldType === 'number'"
:value="numberValue"
v-else-if="fieldType === 'price'"
:value="priceValue"
:disabled="disabled"
class="w-full"
:formatter="(v: string) => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
:parser="(v: string) => v.replace(/,/g, '')"
@update:value="onNumberChange"
@update:value="onPriceChange"
/>
<a-input
v-else-if="fieldType === 'number'"
:value="modelValue"
:disabled="disabled"
inputmode="numeric"
allow-clear
class="w-full"
@update:value="onPlainNumberChange"
@blur="emit('blur')"
/>
<a-textarea
@@ -119,18 +130,36 @@ function onSelectChange(val: string | undefined) {
emit('update:value', val ?? '')
}
const numberValue = computed(() => {
const priceValue = computed(() => {
const n = parseFloat(String(props.modelValue || '').replace(/,/g, ''))
return Number.isFinite(n) ? n : undefined
})
function onNumberChange(val: number | string | null) {
function onPriceChange(val: number | string | null) {
if (val === null || val === undefined || val === '') {
emit('update:value', '')
return
}
emit('update:value', String(val))
}
function normalizePlainNumberInput(value: string): string {
const latin = value.replace(/[۰-۹]/g, (d) => String('۰۱۲۳۴۵۶۷۸۹'.indexOf(d)))
let out = ''
let hasDot = false
for (const ch of latin.replace(/,/g, '')) {
if (ch >= '0' && ch <= '9') out += ch
else if (ch === '.' && !hasDot) {
hasDot = true
out += ch
}
}
return out
}
function onPlainNumberChange(val: string) {
emit('update:value', normalizePlainNumberInput(val ?? ''))
}
</script>
<style scoped>
@@ -1,7 +1,7 @@
import type { Const } from '@/model/configuration'
import { isStoreApp } from '@/utils/config'
export type SettingFieldType = 'text' | 'number' | 'switch' | 'select' | 'longtext'
export type SettingFieldType = 'text' | 'number' | 'price' | 'switch' | 'select' | 'longtext'
/** کلیدهای legacy — در پنل نمایش داده نمی‌شوند */
export const HIDDEN_LEGACY_SETTING_KEYS = new Set([
@@ -38,7 +38,8 @@ export function isSettingVisible(key: string | undefined | null): boolean {
export const SETTING_TYPE_OPTIONS = [
{ key: 'text', value: 'متن کوتاه' },
{ key: 'number', value: 'عدد' },
{ key: 'number', value: 'عدد / شماره' },
{ key: 'price', value: 'مبلغ (ریال)' },
{ key: 'switch', value: 'روشن/خاموش' },
{ key: 'select', value: 'انتخابی' },
{ key: 'longtext', value: 'متن بلند' }
@@ -52,14 +53,14 @@ const KEY_TYPE_FALLBACK: Record<string, SettingFieldType> = {
text_rule: 'longtext',
text_about: 'longtext',
fee_service_charge_percentage: 'number',
fee_single: 'number',
buy_fee: 'number',
sell_fee: 'number',
fee_cash: 'number',
fee_single: 'price',
buy_fee: 'price',
sell_fee: 'price',
fee_cash: 'price',
fee_free: 'number',
min_withdraw: 'number',
min_first_buy: 'number',
minimum_sell: 'number',
min_withdraw: 'price',
min_first_buy: 'price',
minimum_sell: 'price',
gift_for_referrer: 'number',
gift_for_referral: 'number',
referral_bonus_amount: 'text',
@@ -135,7 +136,7 @@ export function referralRequiredToString(checked: boolean): string {
export function resolveSettingFieldType(row: Pick<Const, 'key' | 'type'>): SettingFieldType {
const raw = (row.type || '').trim().toLowerCase()
if (['text', 'number', 'switch', 'select', 'longtext'].includes(raw)) {
if (['text', 'number', 'price', 'switch', 'select', 'longtext'].includes(raw)) {
return raw as SettingFieldType
}
if (row.key && KEY_TYPE_FALLBACK[row.key]) {
@@ -198,9 +199,12 @@ export function formatValueForSave(
if (type === 'switch') {
return switchValueFromChecked(key, isSwitchOn(value) || (key === REFERRAL_REQUIRED_KEY && isReferralRequired(value)))
}
if (type === 'number') {
if (type === 'price') {
return value === '' ? '0' : String(value).replace(/,/g, '')
}
if (type === 'number') {
return String(value ?? '').replace(/,/g, '')
}
return value ?? ''
}