fix some bugs

This commit is contained in:
2026-06-23 22:31:07 +03:30
parent 4e7d6bca00
commit 71764f7e9a
68 changed files with 1941 additions and 1288 deletions
+131
View File
@@ -0,0 +1,131 @@
import { m } from '@/utils/metalLabels'
import { metalDisplayUnit } from '@/utils/metalWeight'
/** برچسب‌های پرتکرار پنل ادمین که «طلا» در متن دارند */
export const metalLabel = {
goldBalance: () => m('تراز طلایی'),
goldCommission: () => m('کارمزد طلایی'),
goldWallet: () => m('کیف پول طلایی'),
goldWalletShort: () => m('طلایی'),
goldAmount: () => m('مقدار طلا'),
goldInventory: () => m('موجودی طلایی'),
goldGramPriceCustomer: () => m('قیمت هر گرم طلا برای مشتری (ریال)'),
goldGramPriceOriginal: () => m('قیمت هر گرم طلا بدون سود (ریال)'),
goldGramPriceOriginalSlash: () => m('/قیمت هر گرم طلا بدون سود (ریال)'),
customersGold: () => m('طلای مشتریان'),
goldValueInRial: () => m('ارزش طلا به ریال'),
goldWalletCharge: () => m('شارژ کیف پول طلایی'),
goldWalletBalance: () => m('موجودی طلایی (گرم)'),
goldWalletBalanceGram: () => m('موجودی کیف طلا (گرم)'),
goldInTransaction: () => m('مقدار طلا طی تراکنش (گرم)'),
goldWalletTitle: () => m('کیف پول طلا'),
goldPlaceholder: () => m('مقدار طلا'),
goldUnit: () => m('طلا'),
goldChargeShort: () => m('شارژ طلایی'),
manageGoldCash: () => m('مدیریت موجودی ریالی و طلایی'),
goldGifts: () => m('هدایای طلا'),
goldTradeBuySell: (direction: 1 | 2 | number) =>
m(`قیمت ${direction === 1 ? 'خرید' : 'فروش'} طلا:`),
totalGoldWallet: () => m('مجموع موجودی کیف طلا'),
goldWalletTab: () => m('کیف طلا'),
}
export function walletMetalBalanceTitle(metalId: number, label?: string) {
const unit = metalDisplayUnit(metalId)
switch (metalId) {
case 1:
return m(`موجودی کیف طلا (${unit})`)
case 2:
return m(`موجودی کیف نقره (${unit})`)
case 3:
return m(`موجودی کیف مس (${unit})`)
default:
return label ? `موجودی کیف ${label} (${unit})` : metalLabel.goldWalletBalanceGram()
}
}
export function customerWalletMetalBalanceTitle(metalId: number, label?: string) {
const unit = metalDisplayUnit(metalId)
switch (metalId) {
case 1:
return m(`موجودی طلایی (${unit})`)
case 2:
return m(`موجودی نقره (${unit})`)
case 3:
return m(`موجودی مس (${unit})`)
default:
return label ? `موجودی ${label} (${unit})` : metalLabel.goldWalletBalance()
}
}
export function totalMetalWalletTitle(metalId: number, label?: string) {
const unit = metalDisplayUnit(metalId)
switch (metalId) {
case 1:
return m(`مجموع موجودی کیف طلا`)
case 2:
return m(`مجموع موجودی کیف نقره`)
case 3:
return m(`مجموع موجودی کیف مس`)
default:
return label ? `مجموع موجودی کیف ${label}` : metalLabel.totalGoldWallet()
}
}
export function metalBalanceTitle(metalId: number, label?: string) {
switch (metalId) {
case 1:
return metalLabel.goldBalance()
case 2:
return m('تراز نقره')
case 3:
return m('تراز مس')
default:
return label ? `تراز ${label}` : metalLabel.goldBalance()
}
}
export function metalBalanceTitleWithUnit(metalId: number, label?: string) {
const unit = metalDisplayUnit(metalId)
return `${metalBalanceTitle(metalId, label)} (${unit})`
}
export function transactionMetalAmountTitle(metalId: number, label?: string) {
const unit = metalDisplayUnit(metalId)
switch (metalId) {
case 1:
return m(`مقدار طلا طی تراکنش (${unit})`)
case 2:
return m(`مقدار نقره طی تراکنش (${unit})`)
case 3:
return m(`مقدار مس طی تراکنش (${unit})`)
default:
return label ? `مقدار ${label} طی تراکنش (${unit})` : metalLabel.goldInTransaction()
}
}
export function dealPriceAtTransactionTitle(metalId: number, label?: string) {
switch (metalId) {
case 1:
return m('قیمت زمان معامله طلا (ریال)')
case 2:
return m('قیمت زمان معامله نقره (ریال)')
case 3:
return m('قیمت زمان معامله مس (ریال)')
default:
return label ? `قیمت زمان معامله ${label} (ریال)` : 'قیمت زمان معامله (ریال)'
}
}
export function metalCommissionTitle(metalId: number, label?: string) {
switch (metalId) {
case 1:
return metalLabel.goldCommission()
case 2:
return m('کارمزد نقره')
case 3:
return m('کارمزد مس')
default:
return label ? `کارمزد ${label}` : metalLabel.goldCommission()
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ export function mapCategoriesToSelectItems(
}))
}
/** همان منبع جدول دسته‌بندی‌ها — قبل از خواندن، همگام‌سازی می‌کند */
/** همان منبع جدول دسته‌بندی‌ها — دسته‌های جدید از محصولات اضافه می‌شوند؛ ترتیب دستی حفظ می‌شود */
export async function syncAndLoadCategories(options?: {
selectOnly?: boolean
metalHint?: string
+5
View File
@@ -1,3 +1,5 @@
import { setCachedMainMetal } from '@/utils/metalLabels'
export function getConfigApp(key: string) {
const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user : {}
@@ -29,11 +31,14 @@ async function bootstrapSettingsFromApi(): Promise<void> {
const list = Array.isArray(rows) ? rows : []
const isStoreRow = list.find((item) => item.key === 'is_store')
const mainWalletRow = list.find((item) => item.key === 'main_wallet_products')
const mainMetalRow = list.find((item) => item.key === 'main_metal')
storeModeFromSettings = isStoreRow ? isSwitchOn(isStoreRow.value) : false
setCachedMainMetal(mainMetalRow?.value)
const { setCachedMainWalletProductIds } = await import('@/components/mobile/utils/wallet')
setCachedMainWalletProductIds(parseMainWalletProductIds(mainWalletRow?.value))
} catch {
storeModeFromSettings = false
setCachedMainMetal(null)
const { setCachedMainWalletProductIds } = await import('@/components/mobile/utils/wallet')
setCachedMainWalletProductIds([])
} finally {
+36
View File
@@ -0,0 +1,36 @@
import { ref } from 'vue'
export const DEFAULT_MAIN_METAL = 'طلا'
const mainMetalRef = ref(DEFAULT_MAIN_METAL)
export function resolveMainMetal(value?: string | number | null): string {
const normalized = value?.toString().trim()
return normalized || DEFAULT_MAIN_METAL
}
export function setCachedMainMetal(value?: string | number | null): void {
mainMetalRef.value = resolveMainMetal(value)
}
export function getMainMetal(): string {
return mainMetalRef.value
}
export function useMainMetalRef() {
return mainMetalRef
}
/** جایگزینی طلایی/طلای/طلا با نام فلز — بدون صفت مسی/طلایی */
export function applyMainMetalText(text: string, mainMetal = getMainMetal()): string {
if (!text || mainMetal === DEFAULT_MAIN_METAL) return text
return text
.replace(/طلایی/g, mainMetal)
.replace(/طلای/g, mainMetal)
.replace(/طلا/g, mainMetal)
}
export function m(text: string): string {
return applyMainMetalText(text)
}
+68
View File
@@ -0,0 +1,68 @@
import { TRADE_WEIGHT_UNIT_GRAM, TRADE_WEIGHT_UNIT_KILOGRAM } from '@/utils/weightUnit'
export const METAL_ID_GOLD = 1
export const METAL_ID_SILVER = 2
export const METAL_ID_COPPER = 3
/** واحد نمایش موجودی/تراز هر فلز — مس کیلوگرم، بقیه گرم */
export function metalDisplayUnit(metalId: number): string {
return metalId === METAL_ID_COPPER ? TRADE_WEIGHT_UNIT_KILOGRAM : TRADE_WEIGHT_UNIT_GRAM
}
export function isMetalKilogram(metalId: number): boolean {
return metalId === METAL_ID_COPPER
}
/** تبدیل مقدار ذخیره‌شده به گرم (برای محاسبات ریالی) */
export function gramsToMetalDisplay(grams: number, metalId: number): number {
return isMetalKilogram(metalId) ? grams / 1000 : grams
}
/** مقدار نمایشی از گرم */
export function formatMetalWeightFromGrams(
grams: number,
metalId: number,
decimals = 3
): string {
const value = gramsToMetalDisplay(grams, metalId)
return formatMetalDisplayValue(value, metalId, decimals)
}
/** مقدار از قبل در واحد نمایشی فلز */
export function formatMetalDisplayValue(
value: number,
metalId: number,
decimals = 3
): string {
const unit = metalDisplayUnit(metalId)
return `${Number(Number(value).toFixed(decimals))} ${unit}`
}
export function formatMetalDisplayValuePlain(
value: number,
metalId: number,
decimals = 3
): string {
return Number(Number(value).toFixed(decimals)).toLocaleString('fa-IR', {
maximumFractionDigits: decimals
})
}
export function metalCellValue(
record: Record<string, unknown>,
metalId: number,
prefix = 'metal_gold'
): number {
const flatKey = `${prefix}_${metalId}`
if (record[flatKey] != null) {
return Number(record[flatKey])
}
const mapKey = prefix === 'wallet_metal_gold' ? 'wallet_metal_gold' : 'metal_gold'
const map = record[mapKey] as Record<string, number> | undefined
if (!map) {
return 0
}
return Number(map[String(metalId)] ?? 0)
}
+14
View File
@@ -13,3 +13,17 @@ export function resolveTradeWeightUnit(settingValue?: string | number | null) {
export function weightFieldLabelForUnit(unit?: string | null) {
return isKilogramUnit(unit) ? 'وزن به کیلوگرم' : 'وزن به گرم'
}
export function formatAmountWithUnit(
value: number | null | undefined,
unit?: string | null,
decimals = 3
): string {
if (value == null || Number.isNaN(Number(value))) {
return '-'
}
const resolvedUnit = (unit ?? TRADE_WEIGHT_UNIT_GRAM).trim() || TRADE_WEIGHT_UNIT_GRAM
return `${Number(Number(value).toFixed(decimals))} ${resolvedUnit}`
}