Display and accept SuperAdmin money amounts in tomans.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,7 +1,16 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { fromGroupedInput, toGroupedDisplay } from '@/utils/money'
|
import {
|
||||||
|
fromGroupedInput,
|
||||||
|
rialToToman,
|
||||||
|
toGroupedDisplay,
|
||||||
|
tomanToRial,
|
||||||
|
} from '@/utils/money'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Money field bound to **rial** storage values (API/DB).
|
||||||
|
* User types and sees **toman** (÷10 / ×10 at the edges).
|
||||||
|
*/
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
value: number | null | undefined
|
value: number | null | undefined
|
||||||
@@ -22,10 +31,11 @@ const emit = defineEmits<{
|
|||||||
(e: 'update:value', value: number): void
|
(e: 'update:value', value: number): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const display = computed(() => toGroupedDisplay(props.value ?? 0))
|
const display = computed(() => toGroupedDisplay(rialToToman(props.value ?? 0)))
|
||||||
|
|
||||||
function onInput(raw: string | number) {
|
function onInput(raw: string | number) {
|
||||||
emit('update:value', fromGroupedInput(String(raw ?? ''), props.allowNegative))
|
const toman = fromGroupedInput(String(raw ?? ''), props.allowNegative)
|
||||||
|
emit('update:value', tomanToRial(toman))
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -351,8 +351,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :md="8">
|
<a-col :xs="24" :md="8">
|
||||||
<a-form-item label="قیمت دوره (ریال)">
|
<a-form-item label="قیمت دوره (تومان)">
|
||||||
<MoneyInput v-model:value="form.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="form.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -397,8 +397,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :md="8">
|
<a-col :xs="24" :md="8">
|
||||||
<a-form-item label="مبلغ (ریال)">
|
<a-form-item label="مبلغ (تومان)">
|
||||||
<MoneyInput v-model:value="renewForm.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="renewForm.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -466,8 +466,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-form-item label="قیمت دوره (ریال)">
|
<a-form-item label="قیمت دوره (تومان)">
|
||||||
<MoneyInput v-model:value="createForm.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="createForm.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|||||||
@@ -377,8 +377,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :md="8">
|
<a-col :xs="24" :md="8">
|
||||||
<a-form-item label="قیمت دوره (ریال)">
|
<a-form-item label="قیمت دوره (تومان)">
|
||||||
<MoneyInput v-model:value="form.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="form.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
@@ -426,8 +426,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xs="24" :md="8">
|
<a-col :xs="24" :md="8">
|
||||||
<a-form-item label="مبلغ (ریال)">
|
<a-form-item label="مبلغ (تومان)">
|
||||||
<MoneyInput v-model:value="renewForm.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="renewForm.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ onMounted(loadTenants)
|
|||||||
:class="{ active: toneFilter === 'healthy' }"
|
:class="{ active: toneFilter === 'healthy' }"
|
||||||
@click="toggleToneFilter('healthy')"
|
@click="toggleToneFilter('healthy')"
|
||||||
>
|
>
|
||||||
بالای ۱۰۰٬۰۰۰ — سبز
|
بالای ۱۰٬۰۰۰ — سبز
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -130,7 +130,7 @@ onMounted(loadTenants)
|
|||||||
:class="{ active: toneFilter === 'warning' }"
|
:class="{ active: toneFilter === 'warning' }"
|
||||||
@click="toggleToneFilter('warning')"
|
@click="toggleToneFilter('warning')"
|
||||||
>
|
>
|
||||||
۱۰٬۰۰۰ تا ۱۰۰٬۰۰۰ — زرد
|
۱٬۰۰۰ تا ۱۰٬۰۰۰ — زرد
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -138,7 +138,7 @@ onMounted(loadTenants)
|
|||||||
:class="{ active: toneFilter === 'critical' }"
|
:class="{ active: toneFilter === 'critical' }"
|
||||||
@click="toggleToneFilter('critical')"
|
@click="toggleToneFilter('critical')"
|
||||||
>
|
>
|
||||||
زیر ۱۰٬۰۰۰ — قرمز
|
زیر ۱٬۰۰۰ — قرمز
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -422,11 +422,11 @@ onMounted(async () => {
|
|||||||
<span>موجودی کیف پول</span>
|
<span>موجودی کیف پول</span>
|
||||||
<a-tag v-if="form.isBlocked" color="error">ارسال مسدود</a-tag>
|
<a-tag v-if="form.isBlocked" color="error">ارسال مسدود</a-tag>
|
||||||
</div>
|
</div>
|
||||||
<strong>{{ formatNumber(summary.balanceRials) }} <small>ریال</small></strong>
|
<strong>{{ formatMoney(summary.balanceRials) }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card sky">
|
<div class="stat-card sky">
|
||||||
<span>قیمت هر پارت</span>
|
<span>قیمت هر پارت</span>
|
||||||
<strong>{{ formatNumber(summary.perPartRials) }} <small>ریال</small></strong>
|
<strong>{{ formatMoney(summary.perPartRials) }}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card emerald">
|
<div class="stat-card emerald">
|
||||||
<span>امروز</span>
|
<span>امروز</span>
|
||||||
@@ -458,7 +458,7 @@ onMounted(async () => {
|
|||||||
<MoneyInput
|
<MoneyInput
|
||||||
v-model:value="chargeForm.amountRials"
|
v-model:value="chargeForm.amountRials"
|
||||||
allow-negative
|
allow-negative
|
||||||
placeholder="مبلغ (ریال)"
|
placeholder="مبلغ (تومان)"
|
||||||
/>
|
/>
|
||||||
<a-input v-model:value="chargeForm.note" size="large" placeholder="توضیح (اختیاری)" />
|
<a-input v-model:value="chargeForm.note" size="large" placeholder="توضیح (اختیاری)" />
|
||||||
<a-button type="primary" size="large" :loading="charging" @click="openChargeConfirm">
|
<a-button type="primary" size="large" :loading="charging" @click="openChargeConfirm">
|
||||||
|
|||||||
@@ -396,8 +396,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-form-item v-if="!form.isFree" label="قیمت دوره (ریال)">
|
<a-form-item v-if="!form.isFree" label="قیمت دوره (تومان)">
|
||||||
<MoneyInput v-model:value="form.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="form.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<p v-else class="field-hint">
|
<p v-else class="field-hint">
|
||||||
دوره رایگان فعال است — مبلغ صفر میشود. مدت ۱ / ۳ / ۶ / ۱۲ ماه میتواند رایگان باشد.
|
دوره رایگان فعال است — مبلغ صفر میشود. مدت ۱ / ۳ / ۶ / ۱۲ ماه میتواند رایگان باشد.
|
||||||
@@ -448,8 +448,8 @@ onMounted(loadDetail)
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-form-item v-if="!renewForm.isFree" label="مبلغ (ریال)">
|
<a-form-item v-if="!renewForm.isFree" label="مبلغ (تومان)">
|
||||||
<MoneyInput v-model:value="renewForm.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="renewForm.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<p v-else class="field-hint">
|
<p v-else class="field-hint">
|
||||||
دوره رایگان — مبلغ صفر. مدت ۱ / ۳ / ۶ / ۱۲ ماه میتواند رایگان باشد.
|
دوره رایگان — مبلغ صفر. مدت ۱ / ۳ / ۶ / ۱۲ ماه میتواند رایگان باشد.
|
||||||
@@ -523,8 +523,8 @@ onMounted(loadDetail)
|
|||||||
<a-form-item label="دوره رایگان">
|
<a-form-item label="دوره رایگان">
|
||||||
<a-switch v-model:checked="createForm.isFree" />
|
<a-switch v-model:checked="createForm.isFree" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item v-if="!createForm.isFree" label="قیمت دوره (ریال)">
|
<a-form-item v-if="!createForm.isFree" label="قیمت دوره (تومان)">
|
||||||
<MoneyInput v-model:value="createForm.priceRials" placeholder="مثلاً 1,500,000" />
|
<MoneyInput v-model:value="createForm.priceRials" placeholder="مثلاً 150,000" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<p v-else class="field-hint">
|
<p v-else class="field-hint">
|
||||||
دوره رایگان — مبلغ صفر. مدت ۱ / ۳ / ۶ / ۱۲ ماه میتواند رایگان باشد.
|
دوره رایگان — مبلغ صفر. مدت ۱ / ۳ / ۶ / ۱۲ ماه میتواند رایگان باشد.
|
||||||
|
|||||||
+20
-2
@@ -1,4 +1,21 @@
|
|||||||
/** Display/parse helpers for rial money inputs with thousand separators. */
|
/**
|
||||||
|
* SuperAdmin money helpers.
|
||||||
|
*
|
||||||
|
* Storage / product remote APIs use integer **rials**.
|
||||||
|
* SuperAdmin UI displays and accepts **tomans** (rial ÷ 10).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Convert stored rial amount to toman for display/input. */
|
||||||
|
export function rialToToman(value: number | null | undefined) {
|
||||||
|
if (value == null || Number.isNaN(Number(value))) return 0
|
||||||
|
return Math.trunc(Number(value) / 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert UI toman amount to stored rial. */
|
||||||
|
export function tomanToRial(value: number | null | undefined) {
|
||||||
|
if (value == null || Number.isNaN(Number(value))) return 0
|
||||||
|
return Math.trunc(Number(value)) * 10
|
||||||
|
}
|
||||||
|
|
||||||
export function toGroupedDisplay(value: number | null | undefined) {
|
export function toGroupedDisplay(value: number | null | undefined) {
|
||||||
if (value == null || Number.isNaN(Number(value))) return ''
|
if (value == null || Number.isNaN(Number(value))) return ''
|
||||||
@@ -23,7 +40,8 @@ export function formatNumber(value: number | null | undefined) {
|
|||||||
return new Intl.NumberFormat('fa-IR').format(value)
|
return new Intl.NumberFormat('fa-IR').format(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Format a **rial** storage value as toman for SuperAdmin UI. */
|
||||||
export function formatMoney(value: number | null | undefined) {
|
export function formatMoney(value: number | null | undefined) {
|
||||||
if (value == null) return '—'
|
if (value == null) return '—'
|
||||||
return `${formatNumber(value)} ریال`
|
return `${formatNumber(rialToToman(value))} تومان`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user