fix some bugs

This commit is contained in:
2026-07-14 13:53:20 +03:30
parent 76813df062
commit e83daaf28b
9 changed files with 119 additions and 28 deletions
+19 -5
View File
@@ -6,9 +6,18 @@ export function getWallets(wallet?: Wallet | Wallet[]): Wallet[] {
} }
/** کیف اصلی مشتری — بدون fund و بدون product */ /** کیف اصلی مشتری — بدون fund و بدون product */
export function getMainWallet(wallet?: Wallet | Wallet[]): Wallet | undefined { export function getMainWallet(
wallet?: Wallet | Wallet[],
ownerType?: number | null
): Wallet | undefined {
const wallets = getWallets(wallet) const wallets = getWallets(wallet)
return wallets.find((w) => w.fund_id == null && w.product_id == null) return wallets.find((w) => {
if (w.fund_id != null || w.product_id != null) return false
if (ownerType != null && w.owner_type != null && Number(w.owner_type) !== Number(ownerType)) {
return false
}
return true
})
} }
/** پارس setting `main_wallet_products` — id با کاما یا JSON */ /** پارس setting `main_wallet_products` — id با کاما یا JSON */
@@ -63,12 +72,12 @@ export function getMainWalletProductIds(): number[] {
*/ */
export function getCashBalance( export function getCashBalance(
wallet?: Wallet | Wallet[], wallet?: Wallet | Wallet[],
options?: { walletCash?: number | null } options?: { walletCash?: number | null; ownerType?: number | null }
): number { ): number {
if (options?.walletCash != null) { if (options?.walletCash != null) {
return Number(options.walletCash) return Number(options.walletCash)
} }
return getMainWallet(wallet)?.cash ?? 0 return getMainWallet(wallet, options?.ownerType)?.cash ?? 0
} }
/** /**
@@ -77,14 +86,19 @@ export function getCashBalance(
*/ */
export function getGoldBalance( export function getGoldBalance(
wallet?: Wallet | Wallet[], wallet?: Wallet | Wallet[],
options?: { walletGold?: number | null; mainWalletProductIds?: number[] } options?: { walletGold?: number | null; mainWalletProductIds?: number[]; ownerType?: number | null }
): string { ): string {
if (options?.walletGold != null) { if (options?.walletGold != null) {
return Number(options.walletGold).toFixed(3) return Number(options.walletGold).toFixed(3)
} }
const mainWalletProductIds = options?.mainWalletProductIds ?? getMainWalletProductIds() const mainWalletProductIds = options?.mainWalletProductIds ?? getMainWalletProductIds()
const ownerType = options?.ownerType ?? null
const sum = getWallets(wallet).reduce((total, line) => { const sum = getWallets(wallet).reduce((total, line) => {
if (ownerType != null && line.owner_type != null && Number(line.owner_type) !== Number(ownerType)) {
return total
}
const gold = Number(line.gold ?? 0) const gold = Number(line.gold ?? 0)
if (gold <= 0) return total if (gold <= 0) return total
+1
View File
@@ -34,6 +34,7 @@ export interface Customer {
profit_amount: number profit_amount: number
add_user_limit: number add_user_limit: number
trade_active: boolean trade_active: boolean
type?: number
type_str: string type_str: string
gold: number gold: number
moshtari_code?: string | number | null moshtari_code?: string | number | null
+1
View File
@@ -22,6 +22,7 @@ export interface Order {
total_price?: number total_price?: number
goldCash?: number goldCash?: number
goldValue?: number goldValue?: number
target_cash?: number
total_price_original?: number total_price_original?: number
updated_at?: string updated_at?: string
pay_at?: string pay_at?: string
+1
View File
@@ -30,6 +30,7 @@ export interface Wallet {
gold: number gold: number
cash: number cash: number
fund_id?: number | null fund_id?: number | null
owner_type?: number
product_id?: number | null product_id?: number | null
metal_gold?: Record<string, number> metal_gold?: Record<string, number>
customer: User customer: User
+38 -6
View File
@@ -86,13 +86,13 @@
is-line is-line
:title="metalLabel.goldWalletTitle()" :title="metalLabel.goldWalletTitle()"
class="mt-2" class="mt-2"
:value="getGoldBalance(selectedCustomer?.wallet) || '_'" :value="selectedCustomerGoldBalance"
/> />
<BasicInfoItem <BasicInfoItem
is-line is-line
title="کیف پول ریالی" title="کیف پول ریالی"
class="mt-1" class="mt-1"
:value="getCashBalance(selectedCustomer?.wallet) || '_'" :value="selectedCustomerCashBalance"
/> />
</div> </div>
<div class="flex flex-col gap-2 bg-blue-50 p-2 rounded-lg"> <div class="flex flex-col gap-2 bg-blue-50 p-2 rounded-lg">
@@ -185,6 +185,26 @@ const userItems = ref<Customer[]>()
const selectedCustomer = ref<Customer>() const selectedCustomer = ref<Customer>()
let updateKey = ref<number>(0) let updateKey = ref<number>(0)
const selectedCustomerGoldBalance = computed(() => {
const customer = selectedCustomer.value
if (customer?.wallet_gold != null) {
return Number(customer.wallet_gold).toFixed(3)
}
return getGoldBalance(customer?.wallet, { ownerType: customer?.type }) || '_'
})
const selectedCustomerCashBalance = computed(() => {
const customer = selectedCustomer.value
if (!customer) return '_'
const balance = getCashBalance(customer.wallet, {
walletCash: customer.wallet_cash,
ownerType: customer.type,
})
return usePrice(Number(balance ?? 0), true, '').trim()
})
async function getCustomers() { async function getCustomers() {
try { try {
loading.value = true loading.value = true
@@ -337,7 +357,11 @@ function info(val: Order) {
userInfoVisible.value = true userInfoVisible.value = true
} }
/** آخرین فیلدی که کاربر ویرایش کرده — برای target_cash هنگام ثبت */
const amountInputLock = ref<'rial' | 'gram' | null>(null)
function calculateCash(val: number) { function calculateCash(val: number) {
amountInputLock.value = 'gram'
// console.log(val) // console.log(val)
if (form.value.price) { if (form.value.price) {
if (form.value.direction === 1) { if (form.value.direction === 1) {
@@ -351,6 +375,7 @@ function calculateCash(val: number) {
} }
function calculateGold(val: number) { function calculateGold(val: number) {
amountInputLock.value = 'rial'
// console.log(val) // console.log(val)
// form.value.goldCash = usePriceWithoutType(form.value.goldCash) // form.value.goldCash = usePriceWithoutType(form.value.goldCash)
if (form.value.price) { if (form.value.price) {
@@ -413,6 +438,7 @@ async function add() {
//reset data //reset data
const resetData = () => { const resetData = () => {
formRef.value?.resetFields() formRef.value?.resetFields()
amountInputLock.value = null
form.value = { form.value = {
direction: 1, direction: 1,
price: 0, price: 0,
@@ -447,11 +473,17 @@ async function ok() {
clearSubmitError() clearSubmitError()
loading.value = true loading.value = true
try { try {
form.value.amount = form.value.goldValue const payload: Order = { ...form.value }
delete form.value.goldValue payload.amount = payload.goldValue
delete form.value.goldCash
await createOrder(form.value) if (amountInputLock.value === 'rial' && form.value.goldCash != null) {
payload.target_cash = Math.round(Number(String(form.value.goldCash).replaceAll(',', '')))
}
delete payload.goldValue
delete payload.goldCash
await createOrder(payload)
message.success('سفارش با موفقیت ثبت شد') message.success('سفارش با موفقیت ثبت شد')
addOrderVisible.value = false addOrderVisible.value = false
resetData() resetData()
@@ -76,11 +76,10 @@
<a-time-picker <a-time-picker
v-else-if="fieldType === 'time'" v-else-if="fieldType === 'time'"
:value="modelValue || undefined" :value="timePickerValue"
:disabled="disabled" :disabled="disabled"
class="w-full" class="w-full"
format="HH:mm" format="HH:mm"
value-format="HH:mm:ss"
:minute-step="5" :minute-step="5"
placeholder="انتخاب ساعت" placeholder="انتخاب ساعت"
@update:value="onTimeChange" @update:value="onTimeChange"
@@ -137,6 +136,7 @@ import TemplateTextField from './TemplateTextField.vue'
import ZaarboxPriceKeyField from './ZaarboxPriceKeyField.vue' import ZaarboxPriceKeyField from './ZaarboxPriceKeyField.vue'
import { hasTemplateField } from './templateFields' import { hasTemplateField } from './templateFields'
import { import {
normalizeTimeValue,
parseSelectOptions, parseSelectOptions,
resolveSettingFieldType, resolveSettingFieldType,
resolveSwitchChecked, resolveSwitchChecked,
@@ -144,6 +144,10 @@ import {
switchValueFromChecked, switchValueFromChecked,
type SettingFieldType type SettingFieldType
} from './settingTypes' } from './settingTypes'
import dayjs, { type Dayjs } from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
dayjs.extend(customParseFormat)
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@@ -207,9 +211,25 @@ function onMultiSelectChange(val: string[] | undefined) {
emit('update:value', list.join(',')) emit('update:value', list.join(','))
} }
function onTimeChange(val: string | string[] | undefined) { function parseTimePickerValue(raw?: string | null): Dayjs | undefined {
const v = Array.isArray(val) ? val[0] : val const normalized = normalizeTimeValue(raw)
emit('update:value', v ?? '') if (!normalized) return undefined
const parsed = dayjs(normalized, 'HH:mm:ss', true)
return parsed.isValid() ? parsed : undefined
}
const timePickerValue = computed(() => parseTimePickerValue(props.modelValue))
function onTimeChange(val: Dayjs | string | null | undefined) {
if (val == null || val === '') {
emit('update:value', '')
emit('blur')
return
}
const parsed = dayjs.isDayjs(val) ? val : dayjs(String(val), 'HH:mm:ss', true)
emit('update:value', parsed.isValid() ? normalizeTimeValue(parsed.format('HH:mm:ss')) : '')
emit('blur') emit('blur')
} }
@@ -132,13 +132,25 @@ const marketPriceLabel = computed(() => {
return usePrice(price) return usePrice(price)
}) })
const goldBalanceDisplay = computed( const goldBalanceDisplay = computed(() => {
() => getGoldBalance(props.selectedCustomer?.wallet) || '_' const customer = props.selectedCustomer
) if (customer?.wallet_gold != null) {
return Number(customer.wallet_gold).toFixed(3)
}
return getGoldBalance(customer?.wallet, { ownerType: customer?.type }) || '_'
})
const cashBalanceDisplay = computed( const cashBalanceDisplay = computed(() => {
() => getCashBalance(props.selectedCustomer?.wallet) || '_' const customer = props.selectedCustomer
) if (!customer) return '_'
const balance = getCashBalance(customer.wallet, {
walletCash: customer.wallet_cash,
ownerType: customer.type,
})
return usePrice(Number(balance ?? 0), true, '').trim()
})
defineExpose({ defineExpose({
validateFields: () => formRef.value?.validateFields(), validateFields: () => formRef.value?.validateFields(),
+10 -4
View File
@@ -409,11 +409,17 @@ async function ok() {
clearSubmitError() clearSubmitError()
loading.value = true loading.value = true
try { try {
form.value.amount = form.value.goldValue const payload: Order = { ...form.value }
delete form.value.goldValue payload.amount = toOrderNumber(form.value.goldValue)
delete form.value.goldCash
await createOrder(form.value) if (amountInputLock.value === 'rial' && form.value.goldCash != null) {
payload.target_cash = Math.round(Number(String(form.value.goldCash).replaceAll(',', '')))
}
delete payload.goldValue
delete payload.goldCash
await createOrder(payload)
message.success('سفارش با موفقیت ثبت شد') message.success('سفارش با موفقیت ثبت شد')
addOrderVisible.value = false addOrderVisible.value = false
closeAddOrder() closeAddOrder()
+6 -2
View File
@@ -474,13 +474,17 @@ async function saveProduct() {
payload.cash_fee_sell_is_percent = normalizeCashFeeFlags(payload.cash_fee_sell_is_percent) payload.cash_fee_sell_is_percent = normalizeCashFeeFlags(payload.cash_fee_sell_is_percent)
if (usesMeltedPriceEditor(payload)) { if (usesMeltedPriceEditor(payload)) {
// ادیتور آبشده/مقداری قیمت اپ را از روی استنتاج تشخیص می‌دهد، نه ستون app_price // آبشده/کاتد: بدون پرچم app_price؛ شمش مقداری با وزن + منبع اپ: app_price برای × وزن در اپ
payload.app_price = false
if (isMeltedTradeGroup(payload.group_type)) { if (isMeltedTradeGroup(payload.group_type)) {
payload.app_price = false
payload.amount = 1 payload.amount = 1
if (!editId) { if (!editId) {
payload.trade_by_quantity = true payload.trade_by_quantity = true
} }
} else if (meltedPriceOption.value === 'app' && Number(payload.amount ?? 0) > 0) {
payload.app_price = true
} else {
payload.app_price = false
} }
payload.direct_price = meltedPriceOption.value === 'fixed' ? 1 : 0 payload.direct_price = meltedPriceOption.value === 'fixed' ? 1 : 0