322 lines
10 KiB
Vue
322 lines
10 KiB
Vue
<template>
|
|
<div class="person-info">
|
|
<v-card v-if="person" class="person-card" elevation="2">
|
|
<v-card-title class="d-flex align-center">
|
|
<v-avatar color="primary" size="40" class="mr-3">
|
|
<v-icon color="white">mdi-account</v-icon>
|
|
</v-avatar>
|
|
<div>
|
|
<div class="text-h6">{{ person.nikename }}</div>
|
|
<div class="text-caption text-medium-emphasis">{{ person.code }}</div>
|
|
</div>
|
|
<v-spacer></v-spacer>
|
|
<v-chip
|
|
:color="getBalanceColor(person.balance.balance_status)"
|
|
size="small"
|
|
variant="flat"
|
|
>
|
|
{{ person.balance.balance_status }}
|
|
</v-chip>
|
|
</v-card-title>
|
|
|
|
<v-card-text>
|
|
<!-- اطلاعات اصلی -->
|
|
<div class="info-section mb-4">
|
|
<h4 class="text-subtitle-1 font-weight-medium mb-2">اطلاعات اصلی</h4>
|
|
<v-row>
|
|
<v-col cols="12" md="6">
|
|
<div class="info-item">
|
|
<span class="info-label">نام کامل:</span>
|
|
<span class="info-value">{{ person.name || 'نامشخص' }}</span>
|
|
</div>
|
|
<div class="info-item" v-if="person.company">
|
|
<span class="info-label">شرکت:</span>
|
|
<span class="info-value">{{ person.company }}</span>
|
|
</div>
|
|
<div class="info-item" v-if="person.mobile">
|
|
<span class="info-label">موبایل:</span>
|
|
<span class="info-value">{{ person.mobile }}</span>
|
|
</div>
|
|
<div class="info-item" v-if="person.tel">
|
|
<span class="info-label">تلفن:</span>
|
|
<span class="info-value">{{ person.tel }}</span>
|
|
</div>
|
|
</v-col>
|
|
<v-col cols="12" md="6">
|
|
<div class="info-item" v-if="person.email">
|
|
<span class="info-label">ایمیل:</span>
|
|
<span class="info-value">{{ person.email }}</span>
|
|
</div>
|
|
<div class="info-item" v-if="person.address">
|
|
<span class="info-label">آدرس:</span>
|
|
<span class="info-value">{{ person.address }}</span>
|
|
</div>
|
|
<div class="info-item" v-if="person.shahr">
|
|
<span class="info-label">شهر:</span>
|
|
<span class="info-value">{{ person.shahr }}</span>
|
|
</div>
|
|
<div class="info-item" v-if="person.ostan">
|
|
<span class="info-label">استان:</span>
|
|
<span class="info-value">{{ person.ostan }}</span>
|
|
</div>
|
|
</v-col>
|
|
</v-row>
|
|
</div>
|
|
|
|
<!-- موجودی مالی -->
|
|
<div class="info-section mb-4">
|
|
<h4 class="text-subtitle-1 font-weight-medium mb-2">موجودی مالی</h4>
|
|
<v-row>
|
|
<v-col cols="12" md="4">
|
|
<v-card variant="outlined" class="balance-card">
|
|
<v-card-text class="text-center">
|
|
<div class="text-caption text-medium-emphasis">بستانکار</div>
|
|
<div class="text-h6 text-success">{{ formatNumber(person.balance.total_bs) }} ریال</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
<v-col cols="12" md="4">
|
|
<v-card variant="outlined" class="balance-card">
|
|
<v-card-text class="text-center">
|
|
<div class="text-caption text-medium-emphasis">بدهکار</div>
|
|
<div class="text-h6 text-error">{{ formatNumber(person.balance.total_bd) }} ریال</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
<v-col cols="12" md="4">
|
|
<v-card variant="outlined" class="balance-card">
|
|
<v-card-text class="text-center">
|
|
<div class="text-caption text-medium-emphasis">موجودی</div>
|
|
<div class="text-h6" :class="getBalanceTextColor(person.balance.balance_status)">
|
|
{{ formatNumber(person.balance.balance) }} ریال
|
|
</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
<div class="text-caption text-medium-emphasis mt-2">
|
|
تعداد تراکنشها: {{ person.balance.transaction_count }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- نوع اشخاص -->
|
|
<div class="info-section mb-4" v-if="person.types && person.types.length > 0">
|
|
<h4 class="text-subtitle-1 font-weight-medium mb-2">نوع اشخاص</h4>
|
|
<div class="d-flex flex-wrap gap-1">
|
|
<v-chip
|
|
v-for="type in person.types"
|
|
:key="type.id"
|
|
size="small"
|
|
variant="tonal"
|
|
color="primary"
|
|
>
|
|
{{ type.name }}
|
|
</v-chip>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- کارتهای بانکی -->
|
|
<div class="info-section mb-4" v-if="person.cards && person.cards.length > 0">
|
|
<h4 class="text-subtitle-1 font-weight-medium mb-2">کارتهای بانکی</h4>
|
|
<v-row>
|
|
<v-col cols="12" md="6" v-for="card in person.cards" :key="card.bank">
|
|
<v-card variant="outlined" class="card-item">
|
|
<v-card-text>
|
|
<div class="d-flex align-center mb-2">
|
|
<v-icon color="primary" class="mr-2">mdi-credit-card</v-icon>
|
|
<span class="font-weight-medium">{{ card.bank }}</span>
|
|
</div>
|
|
<div class="text-caption" v-if="card.card_number">
|
|
شماره کارت: {{ maskCardNumber(card.card_number) }}
|
|
</div>
|
|
<div class="text-caption" v-if="card.account_number">
|
|
شماره حساب: {{ card.account_number }}
|
|
</div>
|
|
<div class="text-caption" v-if="card.shaba_number">
|
|
شماره شبا: {{ card.shaba_number }}
|
|
</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</div>
|
|
|
|
<!-- تراکنشهای اخیر -->
|
|
<div class="info-section" v-if="transactions.length > 0">
|
|
<h4 class="text-subtitle-1 font-weight-medium mb-2">تراکنشهای اخیر</h4>
|
|
<v-table density="compact">
|
|
<thead>
|
|
<tr>
|
|
<th>تاریخ</th>
|
|
<th>نوع</th>
|
|
<th>بستانکار</th>
|
|
<th>بدهکار</th>
|
|
<th>توضیحات</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="transaction in transactions" :key="transaction.id">
|
|
<td>{{ formatDate(transaction.doc_date) }}</td>
|
|
<td>
|
|
<v-chip size="x-small" variant="tonal" color="primary">
|
|
{{ transaction.doc_type }}
|
|
</v-chip>
|
|
</td>
|
|
<td class="text-success" v-if="transaction.bs > 0">
|
|
{{ formatNumber(transaction.bs) }}
|
|
</td>
|
|
<td v-else>-</td>
|
|
<td class="text-error" v-if="transaction.bd > 0">
|
|
{{ formatNumber(transaction.bd) }}
|
|
</td>
|
|
<td v-else>-</td>
|
|
<td>{{ transaction.description || transaction.doc_description }}</td>
|
|
</tr>
|
|
</tbody>
|
|
</v-table>
|
|
</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
|
|
<v-card v-else class="no-data-card" elevation="1">
|
|
<v-card-text class="text-center">
|
|
<v-icon size="48" color="grey" class="mb-3">mdi-account-off</v-icon>
|
|
<div class="text-h6 text-grey">اطلاعات شخص یافت نشد</div>
|
|
<div class="text-caption text-grey">لطفاً نام یا کد شخص را بررسی کنید</div>
|
|
</v-card-text>
|
|
</v-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'PersonInfo',
|
|
props: {
|
|
person: {
|
|
type: Object,
|
|
default: null
|
|
},
|
|
transactions: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
},
|
|
methods: {
|
|
formatNumber(number) {
|
|
return new Intl.NumberFormat('fa-IR').format(number);
|
|
},
|
|
|
|
formatDate(dateString) {
|
|
if (!dateString) return '-';
|
|
// تبدیل تاریخ شمسی به میلادی و نمایش
|
|
return dateString;
|
|
},
|
|
|
|
maskCardNumber(cardNumber) {
|
|
if (!cardNumber) return '-';
|
|
return cardNumber.replace(/(\d{4})(\d{4})(\d{4})(\d{4})/, '$1-$2-$3-$4');
|
|
},
|
|
|
|
getBalanceColor(status) {
|
|
switch (status) {
|
|
case 'بستانکار':
|
|
return 'success';
|
|
case 'بدهکار':
|
|
return 'error';
|
|
default:
|
|
return 'grey';
|
|
}
|
|
},
|
|
|
|
getBalanceTextColor(status) {
|
|
switch (status) {
|
|
case 'بستانکار':
|
|
return 'text-success';
|
|
case 'بدهکار':
|
|
return 'text-error';
|
|
default:
|
|
return 'text-grey';
|
|
}
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.person-info {
|
|
max-width: 100%;
|
|
}
|
|
|
|
.person-card {
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.info-section {
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
|
padding-bottom: 16px;
|
|
}
|
|
|
|
.info-section:last-child {
|
|
border-bottom: none;
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 8px 0;
|
|
border-bottom: 1px solid rgba(0, 0, 0, 0.04);
|
|
}
|
|
|
|
.info-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.info-label {
|
|
font-weight: 500;
|
|
color: rgba(0, 0, 0, 0.7);
|
|
min-width: 80px;
|
|
}
|
|
|
|
.info-value {
|
|
color: rgba(0, 0, 0, 0.9);
|
|
text-align: left;
|
|
}
|
|
|
|
.balance-card {
|
|
border-radius: 8px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.balance-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.card-item {
|
|
border-radius: 8px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.card-item:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.no-data-card {
|
|
border-radius: 12px;
|
|
min-height: 200px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.gap-1 {
|
|
gap: 4px;
|
|
}
|
|
|
|
.gap-2 {
|
|
gap: 8px;
|
|
}
|
|
</style> |