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
@@ -2,7 +2,7 @@
<a-form :model="form" ref="formRef" autocomplete="off">
<div class="space-y-3">
<div class="flex flex-col items-center gap-1 rounded-xl bg-gray-50 px-4 py-3 sm:flex-row sm:justify-center sm:gap-4">
<span class="text-sm text-gray-600">قیمت {{ form.direction === 1 ? 'خرید' : 'فروش' }} طلا:</span>
<span class="text-sm text-gray-600">{{ metalLabel.goldTradeBuySell(form.direction) }}</span>
<span class="text-sm font-700 text-gray-900">{{ marketPriceLabel }}</span>
</div>
@@ -48,7 +48,7 @@
@change="$emit('changeUser', $event)"
/>
</a-form-item>
<BasicInfoItem is-line title="کیف پول طلا" :value="selectedCustomer?.wallet?.[0]?.gold ?? '_'" />
<BasicInfoItem is-line :title="metalLabel.goldWalletTitle()" :value="selectedCustomer?.wallet?.[0]?.gold ?? '_'" />
<BasicInfoItem is-line title="کیف پول ریالی" :value="selectedCustomer?.wallet?.[0]?.cash ?? '_'" />
</div>
@@ -71,7 +71,7 @@
addon-before="گرم"
addon-bg-color="#0A1B37"
addon-text-color="white"
place-holder="مقدار طلا"
:place-holder="metalLabel.goldPlaceholder()"
type="tel"
@onchange="$emit('calculateCash', $event)"
/>
@@ -88,6 +88,7 @@ import type { Order } from '@/model/order'
import type { last } from '@/model/price'
import { inputRules, inputRulesNumber } from '@/utils/inputRules'
import { usePrice } from '@core/utils/usePrice'
import { metalLabel } from '@/utils/adminMetalLabels'
const props = defineProps<{
form: Order
@@ -26,23 +26,18 @@
<BaseIcon icon="vuesax-linear:empty-wallet" size="18" color="#15803d" />
</template>
</MobileStatCard>
<MobileStatCard bordered variant="warning" label="مقدار (گرم)" :value="`${row.amount ?? 0} گرم`">
<template #prefix>
<BaseIcon icon="vuesax-linear:coin" size="18" color="#b45309" />
</template>
</MobileStatCard>
<MobileStatCard bordered variant="warning" label="مقدار" :value="amountLabel(row)" />
<MobileStatCard bordered label="قیمت زمان معامله (ریال)" :value="usePrice(row.price ?? 0, true, '')" />
</div>
<div class="space-y-2">
<MobileStatCard bordered label="قیمت هر گرم طلا برای مشتری (ریال)" :value="usePrice(row.price ?? 0, true, '')" />
<MobileStatCard bordered label="قیمت هر گرم طلا بدون سود (ریال)" :value="usePrice(row.price_original ?? 0, true, '')" />
<!-- <MobileStatCard bordered label="قیمت کل لیمان (ریال)" :value="usePrice(row.total_price_liman ?? 0, true, '')" />-->
<MobileStatCard bordered label="کارمزد" :value="serviceChargeLabel(row)" />
<MobileStatCard bordered label="قیمت کل بدون سود (ریال)" :value="usePrice(row.total_price_original ?? 0, true, '')" />
<MobileStatCard bordered label="سود هر گرم (ریال)" :value="usePrice(row.fee ?? 0, true, '')" />
<MobileStatCard bordered label="کارمزد طلایی" :value="serviceChargeLabel(row)" />
<MobileStatCard bordered label="سود واحد (ریال)" :value="usePrice(row.fee ?? 0, true, '')" />
</div>
<MobileInfoGrid>
<MobileDetailRow label="نوع فلز" :value="row.order_metal_label ?? '-'" />
<MobileDetailRow label="کد سفارش" :value="row.id ?? '-'" />
<MobileDetailRow label="شماره موبایل" :value="row.customer?.mobile || '-'" />
<MobileDetailRow label="سود کل (ریال)" :value="usePrice(row.total_fee ?? 0, true, '')" />
@@ -66,6 +61,7 @@ import MobileStatCard from '@/components/mobile/MobileStatCard.vue'
import { isMobile } from '@core/utils/is'
import { toJalali } from '@core/utils/useDataTime'
import { usePrice } from '@core/utils/usePrice'
import { formatAmountWithUnit } from '@/utils/weightUnit'
type OrderRow = Order & { sts_str?: string; service_charge?: number | string }
@@ -113,10 +109,14 @@ function createdAtLabel(row: OrderRow) {
return row.created_at ? toJalali(row.created_at) : '-'
}
function amountLabel(row: OrderRow) {
return formatAmountWithUnit(row.amount_display ?? row.amount, row.amount_unit)
}
function serviceChargeLabel(row: OrderRow) {
if (row.service_charge == null || row.service_charge === '') return '-'
const value = Number(row.service_charge)
if (Number.isNaN(value)) return `${row.service_charge} گرم`
return `${parseFloat(value.toFixed(5))} گرم`
if (Number.isNaN(value)) return String(row.service_charge)
return formatAmountWithUnit(value, row.amount_unit)
}
</script>
@@ -6,6 +6,12 @@
<span class="shrink-0 rounded-md border px-1.5 py-0.5 text-xs font-600" :class="directionClass">
{{ directionLabel }}
</span>
<span
v-if="item.order_metal_label"
class="shrink-0 rounded-md border border-amber-300 bg-amber-50 px-1.5 py-0.5 text-xs font-600 text-amber-700"
>
{{ item.order_metal_label }}
</span>
<span class="truncate text-sm font-700 text-gray-900">{{ customerName }}</span>
</div>
<span class="shrink-0 text-xs font-600" :class="statusValueClass">{{ statusLabel }}</span>
@@ -13,7 +19,7 @@
<div class="flex items-center justify-between gap-2 text-xs text-gray-600">
<span>
<span class="text-gray-500">طلا:</span>
<span class="text-gray-500">مقدار:</span>
<span class="font-600 text-gray-900">{{ amountLabel }}</span>
</span>
<span class="font-700 text-gray-900">{{ totalPriceLabel }}</span>
@@ -26,6 +32,7 @@
import type { Order } from '@/model/order'
import MobileCard from '@/components/mobile/MobileCard.vue'
import { usePrice } from '@core/utils/usePrice'
import { formatAmountWithUnit } from '@/utils/weightUnit'
const props = defineProps<{
item: Order & { sts_str?: string; service_charge?: number }
@@ -44,9 +51,8 @@ const directionClass = computed(() =>
const customerName = computed(() => props.item.customer?.name || '-')
const amountLabel = computed(() => {
const amount = props.item.amount
if (amount == null) return '-'
return `${Number(amount.toFixed(3))} گرم`
const amount = props.item.amount_display ?? props.item.amount
return formatAmountWithUnit(amount, props.item.amount_unit)
})
const totalPriceLabel = computed(() => usePrice(props.item.total_price ?? 0, true, ''))
const statusLabel = computed(() => props.item.sts_str || '-')
@@ -42,7 +42,7 @@ import type { TableInput } from '@core/type/baseTable'
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
import Icon from '@core/components/BaseIcon/src/Icon.vue'
import { changeCustomerActivation, getCustomerTable } from '@/api/customer'
import { cols } from '../hooks/orderColumns'
import { buildOrderColumns } from '../hooks/orderColumns'
import { useUserStore } from '@/store/userStore'
import { usePrefix } from '@core/composable/usePrefix'
import { message } from 'ant-design-vue'
@@ -74,22 +74,22 @@ function checkPermission(temp: string) {
const table = ref(null)
const tblProps = ref<any>({
columns: cols,
api: (params: TableInput) => {
columns: buildOrderColumns(),
api: async (params: TableInput) => {
if (props.customerId) {
params.filters = []
params.filters?.push({
field: "customer_id",
type: "text",
field: 'customer_id',
type: 'text',
value: props.customerId,
cr: "and",
op: "eq",
cr: 'and',
op: 'eq',
hidden: false
})
}
return getOrderTable(params)
const data = await getOrderTable(params)
return data
}
//bordered: true
})
const loading = ref<boolean>(false)
+168 -229
View File
@@ -1,239 +1,178 @@
import type { BaseTableColumn } from '@core/type/baseTable'
import { toJalali, toJalaliNoTime, toTime } from '@core/utils/useDataTime'
import { toJalali } from '@core/utils/useDataTime'
import CustomTag from '@/components/CustomTag.vue'
import { usePrice } from '@core/utils/usePrice'
/*import BudgetSelect from '@/components/BudgetSelect.vue'
import { useStaticApiListsStore } from '@/store/staticApisStore'
import type { FilterSelect } from '@/model/filterSelect'
import type { DocItem } from '@/model/docType'*/
import { formatAmountWithUnit } from '@/utils/weightUnit'
//define store
//const store = useStaticApiListsStore()
//document types
/*let docTypes: DocItem[]*/
/*onMounted(async () => {
docTypes = await store.readyDocTypeList()
})
const filteredDocTypes: FilterSelect = docTypes?.map((x: DocItem) => {
return {
label: x.title,
value: x.id
}
})*/
export type OrderMetalColumn = { metal_id: number; label: string; display_unit?: string }
export const cols: BaseTableColumn[] = [
{
title: 'ردیف',
dataIndex: 'id',
key: 'id',
filterable: false,
sortable: false,
customRender: (record: any) => {
return record.index + 1
}
},
{
title: 'کد سفارش',
dataIndex: 'id',
key: 'id',
type: 'Number'
// className: 'column-money'
},
{
title: 'نوع سفارش',
dataIndex: 'direction',
key: 'direction',
filterable: false,
customRender: ({ record }) => {
switch (record.direction) {
case 2:
return (
<div class="flex justify-center">
<CustomTag textColor="#C53030" bgColor="#FECACA">
فروش
</CustomTag>
</div>
)
case 1:
return (
<div class="flex justify-center">
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
خرید
</CustomTag>
</div>
)
export function buildOrderColumns(_metals: OrderMetalColumn[] = []): BaseTableColumn[] {
return [
{
title: 'ردیف',
dataIndex: 'id',
key: 'id',
filterable: false,
sortable: false,
customRender: (record: any) => {
return record.index + 1
}
}
},
{
title: 'نام و نام خانوادگی',
dataIndex: 'customer.name',
key: 'customer.name',
type: 'Text'
},
{
title: 'شماره موبایل',
dataIndex: 'customer.mobile',
key: 'customer.mobile',
type: 'Number'
},
{
title: 'مقدار (گرم)',
dataIndex: 'amount',
key: 'amount',
type: 'Text'
},
/*{
title: 'کارمزد ریالی',
dataIndex: 'service_charge_price',
key: 'service_charge_price',
type: 'Number',
customRender(data) {
return usePrice(data.record?.service_charge_price ?? 0, true, '')
}
// className: 'column-money'
},*/
{
title: 'کارمزد طلایی',
dataIndex: 'service_charge',
key: 'service_charge',
type: 'Number',
customRender(data) {
return data.record?.service_charge
}
// className: 'column-money'
},
{
title: 'قیمت هر گرم طلا برای مشتری (ریال)',
dataIndex: 'price',
key: 'price',
type: 'Text',
customRender(data) {
return usePrice(data.record?.price ?? 0, true, '')
}
},
/* {
title: 'قیمت هر گرم طلا در لیمان',
dataIndex: 'limanPrice',
key: 'limanPrice',
type: 'Text',
customRender(data) {
return usePrice(data.record?.total_price_liman ?? 0, true, '')
}
},*/
{
title: 'قیمت کل برای مشتری (ریال)',
dataIndex: 'total_price',
key: 'total_price',
type: 'Text',
customRender(data) {
return usePrice(data.record?.total_price ?? 0, true, '')
}
},
{
title: 'وضعیت',
dataIndex: 'sts',
key: 'sts',
filterable: false,
customRender: ({ record }) => {
switch (record.sts) {
case 1:
return (
<div class="flex justify-center">
<CustomTag textColor="#ca8a04" bgColor="#fef3c7">
{record.sts_str}
</CustomTag>
</div>
)
case 2:
return (
<div class="flex justify-center">
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
{record.sts_str}
</CustomTag>
</div>
)
default:
return (
<div class="flex justify-center">
<CustomTag textColor="#C53030" bgColor="#FECACA">
{record.sts_str}
</CustomTag>
</div>
)
},
{
title: 'کد سفارش',
dataIndex: 'id',
key: 'id',
type: 'Number'
},
{
title: 'نوع سفارش',
dataIndex: 'direction',
key: 'direction',
filterable: false,
customRender: ({ record }) => {
switch (record.direction) {
case 2:
return (
<div class="flex justify-center">
<CustomTag textColor="#C53030" bgColor="#FECACA">
فروش
</CustomTag>
</div>
)
case 1:
return (
<div class="flex justify-center">
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
خرید
</CustomTag>
</div>
)
}
}
}
},
{
title: 'تاریخ ثبت',
dataIndex: 'created_at',
key: 'created_at',
type: 'DateTime',
customRender: (record: any) => {
return toJalali(record.record.created_at)
}
},
/*{
title: 'نقش',
dataIndex: 'user_type_record',
key: 'user_type_record',
type: 'Select',
filterable: false,
sortable: false,
filterComponentProps: {
multiple: true
},
filterField: 'user_type_obj.id',
filterComponent: ReadyUserTypeSelect,
/!* customRender: (record: any) => {
return record.record.user_type_record?.value
}*!/
customRender: ({ record }) => {
const items = record.is_admin ? (
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
ادمین
},
{
title: 'نام و نام خانوادگی',
dataIndex: 'customer.name',
key: 'customer.name',
type: 'Text'
},
{
title: 'شماره موبایل',
dataIndex: 'customer.mobile',
key: 'customer.mobile',
type: 'Number'
},
{
title: 'نوع فلز',
dataIndex: 'order_metal_label',
key: 'order_metal_label',
type: 'Text',
filterable: false,
customRender({ record }) {
return (
<div class="flex justify-center">
<CustomTag textColor="#ca8a04" bgColor="#fef3c7" class={'font-bold px-6'}>
{record.order_metal_label ?? '-'}
</CustomTag>
) : (
record.user_type_obj.map((item: { title: any }, index: any) => {
if (item) {
return (
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
{item?.title}
</CustomTag>
)
}
})
)
return <div class="flex justify-center items-center gap-2">{items}</div>
</div>
)
}
},
{
title: 'مقدار',
dataIndex: 'amount',
key: 'amount',
type: 'Text',
customRender({ record }) {
const amount = record.amount_display ?? record.amount
return formatAmountWithUnit(amount, record.amount_unit)
}
},
{
title: 'کارمزد',
dataIndex: 'service_charge',
key: 'service_charge',
type: 'Number',
customRender({ record }) {
const value = record.service_charge
if (value == null || value === '') {
return '-'
}
},
{
title: 'حوزه',
dataIndex: 'section',
key: 'section'
},
{
title: 'شماره موبایل',
dataIndex: 'mobile',
type: 'Number',
key: 'mobile'
},
{
title: 'تاریخ ثبت',
dataIndex: 'created_at',
key: 'created_at',
type: 'DateTime',
customRender: (record: any) => {
return toJalaliNoTime(record.record.created_at)
return formatAmountWithUnit(Number(value), record.amount_unit)
}
},
{
title: 'قیمت زمان معامله (ریال)',
dataIndex: 'price',
key: 'price',
type: 'Text',
customRender({ record }) {
return usePrice(record.price ?? 0, true, '')
}
},
{
title: 'قیمت کل برای مشتری (ریال)',
dataIndex: 'total_price',
key: 'total_price',
type: 'Text',
customRender(data) {
return usePrice(data.record?.total_price ?? 0, true, '')
}
},
{
title: 'وضعیت',
dataIndex: 'sts',
key: 'sts',
filterable: false,
customRender: ({ record }) => {
switch (record.sts) {
case 1:
return (
<div class="flex justify-center">
<CustomTag textColor="#ca8a04" bgColor="#fef3c7">
{record.sts_str}
</CustomTag>
</div>
)
case 2:
return (
<div class="flex justify-center">
<CustomTag textColor="#25855A" bgColor="#E3F4E9">
{record.sts_str}
</CustomTag>
</div>
)
default:
return (
<div class="flex justify-center">
<CustomTag textColor="#C53030" bgColor="#FECACA">
{record.sts_str}
</CustomTag>
</div>
)
}
},*/
{
title: 'عملیات',
dataIndex: 'action',
key: 'action',
slot: 'action',
fixed: 'right',
filterable: false
}
]
}
},
{
title: 'تاریخ ثبت',
dataIndex: 'created_at',
key: 'created_at',
type: 'DateTime',
customRender: (record: any) => {
return toJalali(record.record.created_at)
}
},
{
title: 'عملیات',
dataIndex: 'action',
key: 'action',
slot: 'action',
fixed: 'right',
filterable: false
}
]
}
export function getOrderColumns(): BaseTableColumn[] {
return buildOrderColumns()
}
+15 -6
View File
@@ -80,6 +80,8 @@ import { getLastPrice } from '@/api/price'
import type { last } from '@/model/price'
import { createOrder } from '@/api/order'
import { isMobile } from '@core/utils/is'
import { metalLabel } from '@/utils/adminMetalLabels'
import { formatAmountWithUnit } from '@/utils/weightUnit'
//loading
const loading = ref<boolean>(false)
@@ -182,11 +184,15 @@ function info(val: Order) {
infoParams.itemsTitle = 'اطلاعات کاربری'
infoParams.items = [
{
key: 'مقدار (گرم)',
value: val.amount ?? '-'
key: 'مقدار',
value: formatAmountWithUnit(val.amount_display ?? val.amount, val.amount_unit)
},
{
key: 'قیمت هر گرم طلا برای مشتری (ریال)',
key: 'نوع فلز',
value: val.order_metal_label ?? '-'
},
{
key: 'قیمت زمان معامله (ریال)',
value: usePrice(val.price ?? 0) ?? '-'
},
{
@@ -194,7 +200,7 @@ function info(val: Order) {
value: usePrice(val.total_price ?? 0) ?? '-'
},
{
key: 'قیمت هر گرم طلا بدون سود (ریال)',
key: metalLabel.goldGramPriceOriginal(),
value: usePrice(val.price_original ?? 0) ?? '-'
},
{
@@ -226,8 +232,11 @@ function info(val: Order) {
value: usePrice(val.service_charge_price ?? 0)
},*/
{
key: 'کارمزد طلایی',
value: val.service_charge ?? '-' + ' گرم'
key: 'کارمزد',
value:
val.service_charge != null && val.service_charge !== ''
? formatAmountWithUnit(Number(val.service_charge), val.amount_unit)
: '-'
},
/* {
key: 'تاریخ تولد',