fix some bug
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<BasicActionSheet
|
||||
v-model:visible="visibleProxy"
|
||||
title="مشخصات کیف پول"
|
||||
modal-width="40rem"
|
||||
:show-button="false"
|
||||
@close="visibleProxy = false"
|
||||
>
|
||||
<template v-if="wallet">
|
||||
<div v-if="isMobile" class="mb-3 text-base font-700">مشخصات کیف پول</div>
|
||||
|
||||
<div class="mb-4 flex flex-col gap-2 rounded-lg bg-gray-100 p-3 md:flex-row md:items-center md:justify-between">
|
||||
<div class="min-w-0">
|
||||
<div class="text-base font-bold">{{ wallet.wallet_subject || '—' }}</div>
|
||||
<div class="mt-1 text-sm text-gray-600">کد کیف پول: {{ wallet.id ?? '—' }}</div>
|
||||
</div>
|
||||
<CustomTag
|
||||
v-bind="kindStyle"
|
||||
class="self-start px-4 font-bold md:self-auto"
|
||||
>
|
||||
{{ wallet.wallet_kind_label || '—' }}
|
||||
</CustomTag>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 grid gap-3 md:grid-cols-2">
|
||||
<BasicInfoItem title="کد مشتری" :value="wallet.customer?.id ?? '—'" />
|
||||
<BasicInfoItem title="نام مشتری" :value="wallet.customer?.name || '—'" />
|
||||
<BasicInfoItem title="موبایل" :value="wallet.customer?.mobile || '—'" />
|
||||
<BasicInfoItem title="فلز مرتبط" :value="wallet.wallet_metal_label || '—'" />
|
||||
</div>
|
||||
|
||||
<div v-if="wallet.wallet_kind === 'product'" class="mb-4 rounded-lg border border-green-200 bg-green-50 p-3">
|
||||
<div class="mb-2 text-sm font-700 text-green-900">اطلاعات محصول</div>
|
||||
<div class="grid gap-3 md:grid-cols-2">
|
||||
<BasicInfoItem title="کد محصول" :value="wallet.product_id ?? '—'" />
|
||||
<BasicInfoItem title="نام محصول" :value="wallet.product_title || wallet.product?.title || '—'" />
|
||||
<BasicInfoItem title="دسته" :value="wallet.product_group_type || '—'" />
|
||||
<BasicInfoItem title="وزن / مقدار" :value="productWeightLabel" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="wallet.wallet_kind === 'fund'" class="mb-4 rounded-lg border border-purple-200 bg-purple-50 p-3">
|
||||
<div class="mb-2 text-sm font-700 text-purple-900">اطلاعات قلک</div>
|
||||
<div class="grid gap-3 md:grid-cols-2">
|
||||
<BasicInfoItem title="کد قلک" :value="wallet.fund_id ?? '—'" />
|
||||
<BasicInfoItem title="عنوان قلک" :value="wallet.fund_title || wallet.fund?.title || '—'" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="mb-4 rounded-lg border border-blue-200 bg-blue-50 p-3 text-sm text-blue-900">
|
||||
کیف اصلی مشتری — موجودی ریالی و طلای آبشده (و محصولات تعریفشده در تنظیمات کیف اصلی) در همین کیف نگهداری میشود.
|
||||
</div>
|
||||
|
||||
<div class="mb-2 text-sm font-700">موجودی</div>
|
||||
<div class="mb-4 grid gap-2 md:grid-cols-3">
|
||||
<div class="rounded-lg border border-gray-200 bg-white p-3 text-center">
|
||||
<div class="mb-1 text-xs text-gray-500">ریال</div>
|
||||
<div class="font-bold break-all">{{ usePrice(wallet.cash ?? 0) }}</div>
|
||||
</div>
|
||||
<div class="rounded-lg border border-gray-200 bg-white p-3 text-center">
|
||||
<div class="mb-1 text-xs text-gray-500">ارزش ریالی فلز</div>
|
||||
<div class="font-bold break-all">{{ usePrice(wallet.gold_to_cash ?? 0) }}</div>
|
||||
</div>
|
||||
<div class="rounded-lg border border-gray-200 bg-white p-3 text-center">
|
||||
<div class="mb-1 text-xs text-gray-500">جمع ارزش</div>
|
||||
<div class="font-bold break-all">{{ usePrice(wallet.total_rial_value ?? 0) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="metalRows.length" class="grid gap-2 md:grid-cols-2">
|
||||
<div
|
||||
v-for="row in metalRows"
|
||||
:key="row.metal_id"
|
||||
class="rounded-lg border border-amber-200 bg-amber-50 p-3"
|
||||
>
|
||||
<div class="text-xs text-amber-800">{{ row.label }}</div>
|
||||
<div class="mt-1 font-bold text-amber-950">{{ row.display }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</BasicActionSheet>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Wallet } from '@/model/wallet'
|
||||
import BasicActionSheet from '@/components/BasicActionSheet.vue'
|
||||
import BasicInfoItem from '@/components/BasicInfoItem.vue'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
import { isMobile } from '@core/utils/is'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { formatMetalDisplayValue, metalCellValue } from '@/utils/metalWeight'
|
||||
import { walletKindTagStyle, walletProductWeightLabel } from '@/utils/walletDisplay'
|
||||
import type { WalletMetalColumn } from '../hooks/walletColumns'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
wallet: Wallet | null
|
||||
metals?: WalletMetalColumn[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:visible', value: boolean): void
|
||||
}>()
|
||||
|
||||
const visibleProxy = computed({
|
||||
get: () => props.visible,
|
||||
set: (value: boolean) => emit('update:visible', value)
|
||||
})
|
||||
|
||||
const kindStyle = computed(() => walletKindTagStyle(props.wallet?.wallet_kind))
|
||||
|
||||
const productWeightLabel = computed(() => walletProductWeightLabel(props.wallet))
|
||||
|
||||
const metalRows = computed(() => {
|
||||
const wallet = props.wallet
|
||||
if (!wallet) return []
|
||||
|
||||
const metals = props.metals?.length ? props.metals : [{ metal_id: 1, label: 'طلا' }]
|
||||
|
||||
return metals
|
||||
.map((metal) => {
|
||||
const value = metalCellValue(wallet as Record<string, unknown>, metal.metal_id)
|
||||
return {
|
||||
metal_id: metal.metal_id,
|
||||
label: metal.label,
|
||||
display: formatMetalDisplayValue(value, metal.metal_id),
|
||||
raw: value
|
||||
}
|
||||
})
|
||||
.filter((row) => row.raw !== 0)
|
||||
})
|
||||
</script>
|
||||
@@ -3,6 +3,16 @@
|
||||
<template #default="{ item: row }">
|
||||
<MobileSheetHeader :title="sheetTitle" :show-title="isMobile" />
|
||||
|
||||
<div class="mb-3 flex items-center justify-between gap-2">
|
||||
<span class="text-sm text-gray-600">نوع کیف</span>
|
||||
<span
|
||||
class="rounded px-2 py-0.5 text-xs font-700"
|
||||
:style="{ color: kindStyle.textColor, backgroundColor: kindStyle.bgColor }"
|
||||
>
|
||||
{{ row.wallet_kind_label || '—' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<MobileStatCard bordered variant="success" label="موجودی ریالی" :value="usePrice(row.cash ?? 0, true, '')">
|
||||
<template #prefix>
|
||||
@@ -10,11 +20,34 @@
|
||||
</template>
|
||||
</MobileStatCard>
|
||||
|
||||
<MobileStatCard
|
||||
v-if="(row.gold_to_cash ?? 0) > 0"
|
||||
bordered
|
||||
variant="neutral"
|
||||
label="ارزش ریالی فلز"
|
||||
:value="usePrice(row.gold_to_cash ?? 0, true, '')"
|
||||
>
|
||||
<template #prefix>
|
||||
<BaseIcon icon="vuesax-linear:coin" size="18" color="#b45309" />
|
||||
</template>
|
||||
</MobileStatCard>
|
||||
|
||||
<MobileStatCard
|
||||
bordered
|
||||
variant="neutral"
|
||||
label="جمع ارزش"
|
||||
:value="usePrice(row.total_rial_value ?? 0, true, '')"
|
||||
>
|
||||
<template #prefix>
|
||||
<BaseIcon icon="vuesax-linear:money-recive" size="18" color="#1d4ed8" />
|
||||
</template>
|
||||
</MobileStatCard>
|
||||
|
||||
<MobileStatCard
|
||||
v-for="entry in metalEntries(row)"
|
||||
:key="entry.metal_id"
|
||||
bordered
|
||||
variant="warning"
|
||||
variant="neutral"
|
||||
:label="walletMetalBalanceTitle(entry.metal_id, entry.label)"
|
||||
:value="entry.display"
|
||||
>
|
||||
@@ -26,8 +59,26 @@
|
||||
|
||||
<MobileInfoGrid>
|
||||
<MobileDetailRow label="کد کیف پول" :value="row.id ?? '-'" />
|
||||
<MobileDetailRow label="موضوع" :value="row.wallet_subject || '-'" />
|
||||
<MobileDetailRow label="کد مشتری" :value="row.customer?.id ?? '-'" />
|
||||
<MobileDetailRow label="نام مشتری" :value="row.customer?.name || '-'" />
|
||||
<MobileDetailRow label="شماره موبایل" :value="row.customer?.mobile ?? '-'" />
|
||||
<MobileDetailRow
|
||||
v-if="row.wallet_kind === 'product'"
|
||||
label="کد محصول"
|
||||
:value="row.product_id ?? '-'"
|
||||
/>
|
||||
<MobileDetailRow
|
||||
v-if="row.wallet_kind === 'product'"
|
||||
label="دسته محصول"
|
||||
:value="row.product_group_type || '-'"
|
||||
/>
|
||||
<MobileDetailRow
|
||||
v-if="row.wallet_kind === 'fund'"
|
||||
label="عنوان قلک"
|
||||
:value="row.fund_title || row.fund?.title || '-'"
|
||||
/>
|
||||
<MobileDetailRow label="فلز مرتبط" :value="row.wallet_metal_label || '-'" />
|
||||
</MobileInfoGrid>
|
||||
</template>
|
||||
</MobileDetailSheet>
|
||||
@@ -44,6 +95,7 @@ import { isMobile } from '@core/utils/is'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { walletMetalBalanceTitle } from '@/utils/adminMetalLabels'
|
||||
import { formatMetalDisplayValue, metalCellValue } from '@/utils/metalWeight'
|
||||
import { walletKindTagStyle, walletSheetTitle } from '@/utils/walletDisplay'
|
||||
import type { WalletMetalColumn } from '../hooks/walletColumns'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -61,7 +113,8 @@ const visibleProxy = computed({
|
||||
set: (value: boolean) => emit('update:visible', value)
|
||||
})
|
||||
|
||||
const sheetTitle = computed(() => props.item?.customer?.name || `کیف پول #${props.item?.id ?? '-'}`)
|
||||
const sheetTitle = computed(() => walletSheetTitle(props.item))
|
||||
const kindStyle = computed(() => walletKindTagStyle(props.item?.wallet_kind))
|
||||
|
||||
function metalEntries(row: Wallet) {
|
||||
const metals = props.metals?.length
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
<template>
|
||||
<MobileCard clickable @click="$emit('open', item)">
|
||||
<div class="space-y-1">
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<span class="min-w-0 truncate text-sm font-700 text-gray-900">{{ customerName }}</span>
|
||||
<span class="shrink-0 text-xs text-gray-400">#{{ item.id ?? '-' }}</span>
|
||||
<div class="space-y-1.5">
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div class="min-w-0">
|
||||
<div class="truncate text-sm font-700 text-gray-900">{{ subjectLine }}</div>
|
||||
<div class="mt-0.5 truncate text-xs text-gray-500">{{ customerName }}</div>
|
||||
</div>
|
||||
<span
|
||||
class="shrink-0 rounded px-1.5 py-0.5 text-[10px] font-700"
|
||||
:style="{ color: kindStyle.textColor, backgroundColor: kindStyle.bgColor }"
|
||||
>
|
||||
{{ kindLabel }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between gap-2 text-xs text-gray-600">
|
||||
<span>
|
||||
<span class="text-gray-500">کد کیف:</span>
|
||||
<span class="font-600 text-gray-900">#{{ item.id ?? '-' }}</span>
|
||||
</span>
|
||||
<span>
|
||||
<span class="text-gray-500">ریال:</span>
|
||||
<span class="font-600 text-gray-900">{{ cashLabel }}</span>
|
||||
</span>
|
||||
<span v-if="metalEntries.length === 1">
|
||||
<span class="text-gray-500">{{ metalEntries[0].label }}:</span>
|
||||
<span class="font-700 text-gray-900">{{ metalEntries[0].display }}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="metalEntries.length > 1"
|
||||
v-if="metalEntries.length"
|
||||
class="flex flex-wrap gap-x-3 gap-y-1 text-xs text-gray-600"
|
||||
>
|
||||
<span v-for="entry in metalEntries" :key="entry.metal_id">
|
||||
@@ -35,6 +43,7 @@ import type { Wallet } from '@/model/wallet'
|
||||
import MobileCard from '@/components/mobile/MobileCard.vue'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { formatMetalDisplayValue, metalCellValue } from '@/utils/metalWeight'
|
||||
import { walletKindTagStyle } from '@/utils/walletDisplay'
|
||||
import type { WalletMetalColumn } from '../hooks/walletColumns'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -47,6 +56,9 @@ defineEmits<{
|
||||
}>()
|
||||
|
||||
const customerName = computed(() => props.item.customer?.name || '-')
|
||||
const subjectLine = computed(() => props.item.wallet_subject || customerName.value)
|
||||
const kindLabel = computed(() => props.item.wallet_kind_label || 'کیف پول')
|
||||
const kindStyle = computed(() => walletKindTagStyle(props.item.wallet_kind))
|
||||
const cashLabel = computed(() => usePrice(props.item.cash ?? 0, true, ''))
|
||||
|
||||
function metalValue(metalId: number): number {
|
||||
|
||||
@@ -45,20 +45,14 @@
|
||||
</div>
|
||||
|
||||
<BaseTable v-if="!isMobile" class="min-h-0 min-w-0 flex-1" v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #action="{ column, record }">
|
||||
<div class="gap-2 flex justify-center">
|
||||
<template #action="{ record }">
|
||||
<div class="flex justify-center gap-2">
|
||||
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('info', record)">
|
||||
<template #title>
|
||||
<span>مشخصات</span>
|
||||
<span>مشخصات کیف پول</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:stickynote" color="#10913A" />
|
||||
</a-tooltip>
|
||||
<a-tooltip placement="bottom" class="cursor-pointer" @click="emits('edit', record)">
|
||||
<template #title>
|
||||
<span>ویرایش</span>
|
||||
</template>
|
||||
<Icon icon="vuesax-linear:edit" color="#4572E9" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</BaseTable>
|
||||
@@ -78,10 +72,8 @@
|
||||
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 } from '@/api/customer'
|
||||
import { buildWalletColumns } from '../hooks/walletColumns'
|
||||
import { usePrefix } from '@core/composable/usePrefix'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { getWalletTable } from '@/api/wallet'
|
||||
import { usePrice } from '../../../../core/utils/usePrice'
|
||||
import WalletMobileCardList from './WalletMobileCardList.vue'
|
||||
@@ -92,7 +84,7 @@ import { formatMetalDisplayValue, metalDisplayUnit } from '@/utils/metalWeight'
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
const mobileListRef = ref<null | { fetch: () => Promise<void> }>(null)
|
||||
const emits = defineEmits(['delete', 'edit', 'add', 'info', 'sums'])
|
||||
const emits = defineEmits(['info', 'sums'])
|
||||
|
||||
const { prefixCls } = usePrefix('pophoverstatus')
|
||||
|
||||
@@ -133,7 +125,6 @@ const tblProps = ref<any>({
|
||||
return data
|
||||
}
|
||||
})
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
function walletSumTone(value?: number) {
|
||||
if (value == null || value >= 0) {
|
||||
@@ -147,19 +138,6 @@ function onMobileSums(payload: unknown) {
|
||||
emits('sums', payload)
|
||||
}
|
||||
|
||||
async function changeCustomerActivationFunction(id: number) {
|
||||
try {
|
||||
loading.value = true
|
||||
await changeCustomerActivation(id)
|
||||
reload()
|
||||
message.success('تغییر وضعیت با موفقیت انجام شد')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function fetch() {
|
||||
await Promise.allSettled([reload(), mobileListRef.value?.fetch?.() as Promise<void>])
|
||||
}
|
||||
|
||||
@@ -2,20 +2,32 @@ import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import { metalLabel, walletMetalBalanceTitle } from '@/utils/adminMetalLabels'
|
||||
import { formatMetalDisplayValue, metalCellValue } from '@/utils/metalWeight'
|
||||
import { walletKindTagStyle } from '@/utils/walletDisplay'
|
||||
|
||||
export type WalletMetalColumn = { metal_id: number; label: string; display_unit?: string }
|
||||
|
||||
function kindTag(record: Record<string, unknown>) {
|
||||
const label = String(record.wallet_kind_label ?? '—')
|
||||
const style = walletKindTagStyle(record.wallet_kind as never)
|
||||
return (
|
||||
<span
|
||||
class="inline-block rounded px-2 py-0.5 text-xs font-600"
|
||||
style={{ color: style.textColor, backgroundColor: style.bgColor }}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export function buildWalletColumns(metals: WalletMetalColumn[] = []): BaseTableColumn[] {
|
||||
const baseColumns: BaseTableColumn[] = [
|
||||
{
|
||||
title: 'ردیف',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
key: 'row_index',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: (record: any) => {
|
||||
return record.index + 1
|
||||
}
|
||||
customRender: (record: { index: number }) => record.index + 1
|
||||
},
|
||||
{
|
||||
title: 'کد کیف پول',
|
||||
@@ -23,6 +35,58 @@ export function buildWalletColumns(metals: WalletMetalColumn[] = []): BaseTableC
|
||||
key: 'id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نوع کیف',
|
||||
dataIndex: 'wallet_kind_label',
|
||||
key: 'wallet_kind_label',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return kindTag(data.record as Record<string, unknown>)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'موضوع / محصول',
|
||||
dataIndex: 'wallet_subject',
|
||||
key: 'wallet_subject',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
const record = data.record
|
||||
const subject = record.wallet_subject || '—'
|
||||
const productId = record.product_id
|
||||
if (record.wallet_kind === 'product' && productId) {
|
||||
return (
|
||||
<div>
|
||||
<div>{subject}</div>
|
||||
<div class="text-xs text-gray-500">کد محصول: {productId}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (record.wallet_kind === 'fund' && record.fund_id) {
|
||||
return (
|
||||
<div>
|
||||
<div>{subject}</div>
|
||||
<div class="text-xs text-gray-500">کد قلک: {record.fund_id}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return subject
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'دسته محصول',
|
||||
dataIndex: 'product_group_type',
|
||||
key: 'product_group_type',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return data.record.product_group_type || '—'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'کد مشتری',
|
||||
dataIndex: 'customer.id',
|
||||
key: 'customer.id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'نام مشتری',
|
||||
dataIndex: 'customer.name',
|
||||
@@ -30,7 +94,16 @@ export function buildWalletColumns(metals: WalletMetalColumn[] = []): BaseTableC
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'موجودی کیف پول (ریال)',
|
||||
title: 'موبایل',
|
||||
dataIndex: 'customer.mobile',
|
||||
key: 'customer.mobile',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return data.record.customer?.mobile || '—'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'موجودی ریالی',
|
||||
dataIndex: 'cash',
|
||||
key: 'cash',
|
||||
type: 'Text',
|
||||
@@ -40,34 +113,53 @@ export function buildWalletColumns(metals: WalletMetalColumn[] = []): BaseTableC
|
||||
}
|
||||
]
|
||||
|
||||
if (metals.length === 0) {
|
||||
return [
|
||||
...baseColumns,
|
||||
{
|
||||
title: metalLabel.goldWalletBalanceGram(),
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
const value = Number(data.record?.gold ?? 0)
|
||||
return formatMetalDisplayValue(value, 1)
|
||||
}
|
||||
const metalColumns: BaseTableColumn[] =
|
||||
metals.length === 0
|
||||
? [
|
||||
{
|
||||
title: metalLabel.goldWalletBalanceGram(),
|
||||
dataIndex: 'gold',
|
||||
key: 'gold',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
const value = Number(data.record?.gold ?? 0)
|
||||
return formatMetalDisplayValue(value, 1)
|
||||
}
|
||||
}
|
||||
]
|
||||
: metals.map((metal) => ({
|
||||
title: walletMetalBalanceTitle(metal.metal_id, metal.label),
|
||||
dataIndex: `metal_gold_${metal.metal_id}`,
|
||||
key: `metal_${metal.metal_id}`,
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
const value = metalCellValue(data.record, metal.metal_id)
|
||||
return formatMetalDisplayValue(value, metal.metal_id)
|
||||
}
|
||||
}))
|
||||
|
||||
const tailColumns: BaseTableColumn[] = [
|
||||
{
|
||||
title: 'ارزش ریالی فلز',
|
||||
dataIndex: 'gold_to_cash',
|
||||
key: 'gold_to_cash',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record.gold_to_cash ?? 0, true, '')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'جمع ارزش (ریال)',
|
||||
dataIndex: 'total_rial_value',
|
||||
key: 'total_rial_value',
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
return usePrice(data.record.total_rial_value ?? 0, true, '')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const metalColumns: BaseTableColumn[] = metals.map((metal) => ({
|
||||
title: walletMetalBalanceTitle(metal.metal_id, metal.label),
|
||||
dataIndex: `metal_gold_${metal.metal_id}`,
|
||||
key: `metal_${metal.metal_id}`,
|
||||
type: 'Text',
|
||||
customRender(data) {
|
||||
const value = metalCellValue(data.record, metal.metal_id)
|
||||
return formatMetalDisplayValue(value, metal.metal_id)
|
||||
}
|
||||
}))
|
||||
]
|
||||
|
||||
return [...baseColumns, ...metalColumns]
|
||||
return [...baseColumns, ...metalColumns, ...tailColumns]
|
||||
}
|
||||
|
||||
export function getWalletColumns(): BaseTableColumn[] {
|
||||
|
||||
@@ -2,167 +2,60 @@
|
||||
<div class="h-full min-h-0">
|
||||
<BasicMainCard>
|
||||
<div class="flex h-full min-h-0 flex-col">
|
||||
<div class="shrink-0 md:hidden">
|
||||
<!-- <div class="bg-gray-100 grid grid-cols-2 gap-3 w-full py-2 px-5">
|
||||
<div class="gap-5 text-xs">
|
||||
<div>مجموع موجودی کیف پول:</div>
|
||||
<div class="font-bold">{{ usePrice(sums?.cash ?? 0) }}</div>
|
||||
</div>
|
||||
<div class="gap-5 text-xs">
|
||||
<div>مجموع موجودی کیف پول:</div>
|
||||
<div class="font-bold">
|
||||
{{ usePrice(sums?.cashToGold.toFixed(2) ?? 0, true, 'گرم') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="gap-5 text-xs">
|
||||
<div>{{ metalLabel.totalGoldWallet() }}:</div>
|
||||
<div class="font-bold">{{ usePrice(sums?.gold ?? 0, true, 'گرم') }}</div>
|
||||
</div>
|
||||
<div class="gap-5 text-xs">
|
||||
<div>{{ metalLabel.totalGoldWallet() }}:</div>
|
||||
<div class="font-bold">{{ usePrice(sums?.goldToCash ?? 0) }}</div>
|
||||
</div>
|
||||
</div>-->
|
||||
<div class="grid grid-cols-3 gap-1 text-xs">
|
||||
<div class="bg-blue-600 text-white rounded p-1">مجموع</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">ریال</div>
|
||||
<div class="bg-blue-600 text-white rounded p-1">وزن</div>
|
||||
<div class="shrink-0 md:hidden">
|
||||
<div class="grid grid-cols-3 gap-1 text-xs">
|
||||
<div class="rounded bg-blue-600 p-1 text-white">مجموع</div>
|
||||
<div class="rounded bg-blue-600 p-1 text-white">ریال</div>
|
||||
<div class="rounded bg-blue-600 p-1 text-white">وزن</div>
|
||||
|
||||
<template v-for="metal in mobileMetalRows" :key="`metal-${metal.metal_id}`">
|
||||
<div class="bg-blue-600 text-white rounded p-1">{{ metal.label }}</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="sumToneClass(metal.goldToCash)"
|
||||
>
|
||||
{{ usePrice(metal.goldToCash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="sumToneClass(metal.gold)"
|
||||
>
|
||||
{{ formatMetalDisplayValue(metal.gold ?? 0, metal.metal_id) }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-for="metal in mobileMetalRows" :key="`metal-${metal.metal_id}`">
|
||||
<div class="rounded bg-blue-600 p-1 text-white">{{ metal.label }}</div>
|
||||
<div class="rounded p-1 text-white" :class="sumToneClass(metal.goldToCash)">
|
||||
{{ usePrice(metal.goldToCash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div class="rounded p-1 text-white" :class="sumToneClass(metal.gold)">
|
||||
{{ formatMetalDisplayValue(metal.gold ?? 0, metal.metal_id) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="bg-blue-600 text-white rounded p-1">کیف پول</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="sumToneClass(sums?.cash)"
|
||||
>
|
||||
{{ usePrice(sums?.cash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div
|
||||
class="text-white rounded p-1"
|
||||
:class="sumToneClass(sums?.cashToGold)"
|
||||
>
|
||||
{{ usePrice(sums?.cashToGold ?? 0, true, '') }}
|
||||
<div class="rounded bg-blue-600 p-1 text-white">کیف پول</div>
|
||||
<div class="rounded p-1 text-white" :class="sumToneClass(sums?.cash)">
|
||||
{{ usePrice(sums?.cash ?? 0, true, '') }}
|
||||
</div>
|
||||
<div class="rounded p-1 text-white" :class="sumToneClass(sums?.cashToGold)">
|
||||
{{ usePrice(sums?.cashToGold ?? 0, true, '') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex min-h-0 flex-1 flex-col">
|
||||
<tbl
|
||||
ref="table"
|
||||
class="h-full min-h-0 w-full"
|
||||
@info="info"
|
||||
@edit="edit"
|
||||
@sums="setSums"
|
||||
@delete="deleteItem"
|
||||
@add="add"
|
||||
/>
|
||||
|
||||
<!-- <BasicMenu :menu="menu" width="13rem" @onChange="tabSelected" />
|
||||
<component :is="selectedComponent" class="mr-5" />-->
|
||||
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
|
||||
</div>
|
||||
<div class="flex min-h-0 flex-1 flex-col">
|
||||
<tbl ref="table" class="h-full min-h-0 w-full" @info="openWalletInfo" @sums="setSums" />
|
||||
</div>
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
<BasicModal
|
||||
v-model:visible="addUserVisible"
|
||||
width="40rem"
|
||||
:title="`${editId ? 'ویرایش' : 'افزودن'} کاربر`"
|
||||
@ok="ok"
|
||||
:loading="loading"
|
||||
@close="addUserVisible = false"
|
||||
>
|
||||
<a-form :model="form" ref="formRef" autocomplete="off">
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<a-form-item label="نام" name="fname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.fname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام خانوادگی" name="lname" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.lname" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره همراه" name="mobile" :rules="inputLenRules(11)">
|
||||
<BasicInput v-model:value="form.mobile" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="تاریخ تولد" name="birth_date" :rules="inputRules()">
|
||||
<BaseDatePicker v-model:value="form.birth_date" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="ایمیل" name="email" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.email" />
|
||||
</a-form-item>-->
|
||||
<!-- <a-form-item label="نام فروشگاه" name="shop_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.shop_name" />
|
||||
</a-form-item>-->
|
||||
<a-form-item label="شماره تلفن" name="phone_number" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.phone_number" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام استان" name="province" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.province" />
|
||||
</a-form-item>
|
||||
<a-form-item label="نام شهر" name="city" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.city" />
|
||||
</a-form-item>
|
||||
<a-form-item label="شماره ملی" name="n_code" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.n_code" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="نام چاپی" name="print_name" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.print_name" />
|
||||
</a-form-item>-->
|
||||
</div>
|
||||
</a-form>
|
||||
</BasicModal>
|
||||
<BasicInfoModal
|
||||
v-model:visible="userInfoVisible"
|
||||
@close="userInfoVisible = false"
|
||||
:title="infoParams.title"
|
||||
:date="infoParams.date"
|
||||
:time="infoParams.time"
|
||||
:type="infoParams.type"
|
||||
itemsTitle="اطلاعات فردی"
|
||||
:name="infoParams.name"
|
||||
:items="infoParams.items"
|
||||
|
||||
<WalletInfoSheet
|
||||
v-model:visible="infoVisible"
|
||||
:wallet="selectedWallet"
|
||||
:metals="catalogMetals"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import BasicInfoModal from '@/components/BasicInfoModal'
|
||||
import { inputLenRules, inputRules } from '@/utils/inputRules'
|
||||
import { useStaticApiListsStore } from '@/store/staticApisStore'
|
||||
import { ref } from 'vue'
|
||||
import tbl from './components/table.vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import BasicInfoModal from '@/components/BasicInfoModal/index.vue'
|
||||
import { message } from 'ant-design-vue/es'
|
||||
import type { Info } from '@/components/BasicInfoModal/model/Info'
|
||||
import { toJalaliNoTime, toTime } from '@core/utils/useDataTime'
|
||||
import { confirmDeleteItem } from '@/utils/confirmModal'
|
||||
import { cloneDeep, sum } from 'lodash'
|
||||
import type { Item } from '@/model/Item'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import { createCustomer, deleteCustomer, updateCustomer } from '@/api/customer'
|
||||
import WalletInfoSheet from './components/WalletInfoSheet.vue'
|
||||
import type { Wallet, WalletTableSums } from '@/model/wallet'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
import type { WalletTableSums } from '@/model/wallet'
|
||||
import { formatMetalDisplayValue } from '@/utils/metalWeight'
|
||||
import type { WalletMetalColumn } from './hooks/walletColumns'
|
||||
|
||||
//loading
|
||||
const loading = ref<boolean>(false)
|
||||
|
||||
//define store
|
||||
const store = useStaticApiListsStore()
|
||||
|
||||
const table = ref<null | { fetch: () => Promise<void> }>(null)
|
||||
const sums = ref<WalletTableSums>()
|
||||
const infoVisible = ref(false)
|
||||
const selectedWallet = ref<Wallet | null>(null)
|
||||
const catalogMetals = ref<WalletMetalColumn[]>([])
|
||||
|
||||
const mobileMetalRows = computed(() => {
|
||||
if (sums.value?.metalBalances?.length) {
|
||||
@@ -195,158 +88,18 @@ function sumToneClass(value?: number) {
|
||||
return 'bg-red-600'
|
||||
}
|
||||
|
||||
//define tbl
|
||||
const table = ref(null)
|
||||
const refreshTable = () => table?.value?.fetch()
|
||||
|
||||
let updateKey = ref<number>(0)
|
||||
|
||||
//role confirm items
|
||||
const confirmItems: Array<Item> = [
|
||||
{
|
||||
value: 'بله',
|
||||
key: true
|
||||
},
|
||||
{
|
||||
value: 'خیر',
|
||||
key: false
|
||||
}
|
||||
]
|
||||
|
||||
//form
|
||||
const form = ref<Customer>({})
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
//info
|
||||
let infoParams = reactive<Info>({})
|
||||
|
||||
function setSums(val) {
|
||||
function setSums(val: WalletTableSums) {
|
||||
sums.value = val
|
||||
catalogMetals.value =
|
||||
val?.metalBalances?.map((metal) => ({
|
||||
metal_id: metal.metal_id,
|
||||
label: metal.label
|
||||
})) ?? []
|
||||
}
|
||||
|
||||
function info(val: Customer) {
|
||||
infoParams.name = val.name
|
||||
infoParams.type = val.mobile
|
||||
infoParams.date = toJalaliNoTime(val.created_at)
|
||||
infoParams.time = toTime(val.created_at)
|
||||
infoParams.itemsTitle = 'اطلاعات کاربری'
|
||||
infoParams.items = [
|
||||
{
|
||||
key: 'کد کاربری',
|
||||
value: val.id ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'شماره ملی',
|
||||
value: val.n_code ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'تاریخ تولد',
|
||||
value: toJalaliNoTime(val.birth_date) ?? '-'
|
||||
},
|
||||
/* {
|
||||
key: 'ایمیل',
|
||||
value: val.email ?? '-'
|
||||
},*/
|
||||
/* {
|
||||
key: 'نام فروشگاه',
|
||||
value: val.shop_name ?? '-'
|
||||
},*/
|
||||
{
|
||||
key: 'شماره تلفن',
|
||||
value: val.phone_number ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام استان',
|
||||
value: val.province ?? '-'
|
||||
},
|
||||
{
|
||||
key: 'نام شهر',
|
||||
value: val.city ?? '-'
|
||||
}
|
||||
/* {
|
||||
key: 'نام چاپی',
|
||||
value: val.print_name ?? '-'
|
||||
}*/
|
||||
]
|
||||
userInfoVisible.value = true
|
||||
}
|
||||
|
||||
//edit
|
||||
let editId: number | undefined = undefined
|
||||
|
||||
async function edit(record: Customer) {
|
||||
addUserVisible.value = true
|
||||
editId = record.id
|
||||
form.value = cloneDeep(record)
|
||||
}
|
||||
|
||||
//add
|
||||
async function add() {
|
||||
loading.value = true
|
||||
editId = undefined
|
||||
// await store.getUsersList()
|
||||
addUserVisible.value = true
|
||||
updateKey.value++
|
||||
resetData()
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
//reset data
|
||||
const resetData = () => {
|
||||
formRef.value?.resetFields()
|
||||
form.value = {
|
||||
fname: '',
|
||||
lname: '',
|
||||
active: false,
|
||||
avatar_id: undefined,
|
||||
sts: undefined,
|
||||
id: undefined,
|
||||
mobile: undefined
|
||||
}
|
||||
}
|
||||
|
||||
//delete
|
||||
const deleteItem = (id: number) => confirmDeleteItem('کاربر', id, deleteCustomer, refreshTable)
|
||||
|
||||
//define selects
|
||||
onMounted(async () => {
|
||||
loading.value = true
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
//add project modal
|
||||
const addUserVisible = ref<boolean>(false)
|
||||
const userInfoVisible = ref<boolean>(false)
|
||||
|
||||
//submit user
|
||||
async function ok() {
|
||||
formRef.value?.validateFields().then(async () => {
|
||||
// console.log('salam', form.value)
|
||||
// return
|
||||
loading.value = true
|
||||
try {
|
||||
if (editId) {
|
||||
await updateCustomer(editId, form.value)
|
||||
} else {
|
||||
await createCustomer(form.value)
|
||||
}
|
||||
addUserVisible.value = false
|
||||
refreshTable()
|
||||
resetData()
|
||||
message.success('عملیات با موفقیت انجام شد')
|
||||
// await getResponsible()
|
||||
// await getQC()
|
||||
// await getManager()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
// message.error('خطا در بارگذاری اطلاعات')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
function openWalletInfo(wallet: Wallet) {
|
||||
selectedWallet.value = wallet
|
||||
infoVisible.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user