forked from morrning/hesabixCore
1159 lines
42 KiB
Vue
1159 lines
42 KiB
Vue
<template>
|
||
<v-toolbar color="toolbar" :title="$t('drawer.inquiry')">
|
||
<template v-slot:prepend>
|
||
<v-tooltip :text="$t('dialog.back')" location="bottom">
|
||
<template v-slot:activator="{ props }">
|
||
<v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text"
|
||
icon="mdi-arrow-right" />
|
||
</template>
|
||
</v-tooltip>
|
||
</template>
|
||
</v-toolbar>
|
||
|
||
<v-container class="pa-0">
|
||
|
||
<v-card :loading="loading" :disabled="loading">
|
||
<v-card-text class="pa-8">
|
||
<!-- نمایش اعتبار کاربر -->
|
||
<v-card variant="elevated" class="mb-8 credit-card" :class="`credit-card-${getCreditCardColor()}`"
|
||
elevation="4">
|
||
<div class="credit-card-background">
|
||
<div class="credit-card-pattern"></div>
|
||
</div>
|
||
|
||
<v-card-text class="pa-8 position-relative">
|
||
<div class="d-flex flex-column flex-md-row align-start align-md-center justify-space-between mb-6">
|
||
<div class="d-flex align-center mb-4 mb-md-0">
|
||
<div class="credit-icon-wrapper me-3">
|
||
<v-icon size="40" color="white">mdi-wallet</v-icon>
|
||
</div>
|
||
<div>
|
||
<h4 class="text-h5 font-weight-bold text-white mb-1">اعتبار فعلی</h4>
|
||
<p class="text-body-2 text-white-lighten-1 mb-0 d-none d-sm-block">موجودی حساب شما برای استفاده از
|
||
سرویسهای استعلام</p>
|
||
<p class="text-caption text-white-lighten-1 mb-0 d-block d-sm-none">موجودی حساب</p>
|
||
</div>
|
||
</div>
|
||
<div class="text-center text-md-right">
|
||
<v-btn color="white" variant="outlined" prepend-icon="mdi-plus" @click="$router.push('/acc/sms/panel')"
|
||
class="add-credit-btn" size="large">
|
||
<span class="d-none d-sm-inline">افزایش اعتبار</span>
|
||
<span class="d-inline d-sm-none">افزایش</span>
|
||
</v-btn>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="credit-amount-section">
|
||
<div class="credit-amount-display">
|
||
<div class="amount-label d-none d-sm-block">موجودی</div>
|
||
<div class="amount-label d-block d-sm-none">موجودی حساب</div>
|
||
<div class="amount-value">
|
||
<span class="amount-number">{{ formatCurrency(businessInfo.smsCharge || 0) }}</span>
|
||
<span class="currency-symbol">ریال</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="credit-status-indicator">
|
||
<v-chip :color="getCreditStatusColor()" size="small" variant="flat" class="status-chip">
|
||
<v-icon start size="16">{{ getCreditStatusIcon() }}</v-icon>
|
||
<span class="d-none d-sm-inline">{{ getCreditStatusText() }}</span>
|
||
<span class="d-inline d-sm-none">{{ getCreditStatusTextShort() }}</span>
|
||
</v-chip>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- هشدار اعتبار کم -->
|
||
<v-alert v-if="hasLowCredit" type="warning" variant="tonal" class="mt-6 credit-alert" border="start">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-alert-circle</v-icon>
|
||
</template>
|
||
<div>
|
||
<strong>اعتبار کم:</strong> اعتبار شما برای استفاده از سرویسهای استعلام کافی نیست.
|
||
لطفاً اعتبار خود را افزایش دهید.
|
||
</div>
|
||
</v-alert>
|
||
</v-card-text>
|
||
</v-card>
|
||
|
||
|
||
|
||
<!-- نمایش سرویسهای فعال -->
|
||
<v-row>
|
||
<!-- تبدیل کد پستی به آدرس -->
|
||
<v-col cols="12" sm="12" md="6" lg="4" v-if="inquirySettings.enablePostalCodeToAddress">
|
||
<v-card variant="outlined" class="service-card h-100" elevation="0" @click="openPostalCodeDialog">
|
||
<div class="service-card-header bg-success-lighten-5 pa-4">
|
||
<div class="d-flex align-center justify-space-between mb-3">
|
||
<div class="d-flex align-center">
|
||
<v-icon size="32" color="success" class="mr-3">mdi-map-marker</v-icon>
|
||
<div>
|
||
<h5 class="text-subtitle-1 font-weight-medium text-success mb-1">تبدیل کد پستی به آدرس</h5>
|
||
<p class="text-caption text-medium-emphasis mb-0">تبدیل خودکار کد پستی به آدرس کامل</p>
|
||
</div>
|
||
</div>
|
||
<v-chip color="success" size="small" variant="flat">
|
||
فعال
|
||
</v-chip>
|
||
</div>
|
||
</div>
|
||
|
||
<v-card-text class="pa-4">
|
||
<div class="d-flex align-center justify-space-between">
|
||
<div>
|
||
<p class="text-body-2 text-medium-emphasis mb-1">کارمزد هر استعلام:</p>
|
||
<p class="text-h6 font-weight-medium text-success">{{ inquirySettings.postalCodeToAddressFee }} ریال
|
||
</p>
|
||
</div>
|
||
<v-btn color="success" variant="outlined" prepend-icon="mdi-magnify"
|
||
@click.stop="openPostalCodeDialog">
|
||
استعلام
|
||
</v-btn>
|
||
</div>
|
||
</v-card-text>
|
||
</v-card>
|
||
</v-col>
|
||
|
||
<!-- تبدیل شماره کارت به شبا -->
|
||
<v-col cols="12" sm="12" md="6" lg="4" v-if="inquirySettings.enableCardToSheba">
|
||
<v-card variant="outlined" class="service-card h-100" elevation="0" @click="openCardToShebaDialog">
|
||
<div class="service-card-header bg-info-lighten-5 pa-4">
|
||
<div class="d-flex align-center justify-space-between mb-3">
|
||
<div class="d-flex align-center">
|
||
<v-icon size="32" color="info" class="mr-3">mdi-credit-card</v-icon>
|
||
<div>
|
||
<h5 class="text-subtitle-1 font-weight-medium text-info mb-1">تبدیل شماره کارت به شبا</h5>
|
||
<p class="text-caption text-medium-emphasis mb-0">تبدیل شماره کارت بانکی به شماره شبا</p>
|
||
</div>
|
||
</div>
|
||
<v-chip color="info" size="small" variant="flat">
|
||
فعال
|
||
</v-chip>
|
||
</div>
|
||
</div>
|
||
|
||
<v-card-text class="pa-4">
|
||
<div class="d-flex align-center justify-space-between">
|
||
<div>
|
||
<p class="text-body-2 text-medium-emphasis mb-1">کارمزد هر استعلام:</p>
|
||
<p class="text-h6 font-weight-medium text-info">{{ inquirySettings.cardToShebaFee }} ریال</p>
|
||
</div>
|
||
<v-btn color="info" variant="outlined" prepend-icon="mdi-magnify" @click.stop="openCardToShebaDialog">
|
||
استعلام
|
||
</v-btn>
|
||
</div>
|
||
</v-card-text>
|
||
</v-card>
|
||
</v-col>
|
||
|
||
<!-- تبدیل حساب به شبا -->
|
||
<v-col cols="12" sm="12" md="6" lg="4" v-if="inquirySettings.enableAccountToSheba">
|
||
<v-card variant="outlined" class="service-card h-100" elevation="0" @click="openAccountToShebaDialog">
|
||
<div class="service-card-header bg-warning-lighten-5 pa-4">
|
||
<div class="d-flex align-center justify-space-between mb-3">
|
||
<div class="d-flex align-center">
|
||
<v-icon size="32" color="warning" class="mr-3">mdi-bank</v-icon>
|
||
<div>
|
||
<h5 class="text-subtitle-1 font-weight-medium text-warning mb-1">تبدیل حساب به شبا</h5>
|
||
<p class="text-caption text-medium-emphasis mb-0">تبدیل شماره حساب بانکی به شماره شبا</p>
|
||
</div>
|
||
</div>
|
||
<v-chip color="warning" size="small" variant="flat">
|
||
فعال
|
||
</v-chip>
|
||
</div>
|
||
</div>
|
||
|
||
<v-card-text class="pa-4">
|
||
<div class="d-flex align-center justify-space-between">
|
||
<div>
|
||
<p class="text-body-2 text-medium-emphasis mb-1">کارمزد هر استعلام:</p>
|
||
<p class="text-h6 font-weight-medium text-warning">{{ inquirySettings.accountToShebaFee }} ریال</p>
|
||
</div>
|
||
<v-btn color="warning" variant="outlined" prepend-icon="mdi-magnify"
|
||
@click.stop="openAccountToShebaDialog">
|
||
استعلام
|
||
</v-btn>
|
||
</div>
|
||
</v-card-text>
|
||
</v-card>
|
||
</v-col>
|
||
</v-row>
|
||
|
||
<!-- پیام عدم وجود سرویس فعال -->
|
||
<v-row v-if="!hasActiveServices">
|
||
<v-col cols="12">
|
||
<v-card variant="outlined" class="pa-8 text-center">
|
||
<v-icon size="64" color="grey-lighten-1" class="mb-4">mdi-information-outline</v-icon>
|
||
<h3 class="text-h5 font-weight-medium text-grey-darken-1 mb-2">هیچ سرویس استعلامی فعال نیست</h3>
|
||
<p class="text-body-1 text-medium-emphasis">در حال حاضر هیچ سرویس استعلامی در سیستم فعال نشده است. لطفاً
|
||
با
|
||
مدیر سیستم تماس بگیرید.</p>
|
||
</v-card>
|
||
</v-col>
|
||
</v-row>
|
||
</v-card-text>
|
||
</v-card>
|
||
</v-container>
|
||
|
||
<!-- دیالوگ تبدیل کد پستی به آدرس -->
|
||
<v-dialog v-model="postalCodeDialog" max-width="500px" persistent>
|
||
<v-card>
|
||
<v-card-title class="text-h6 font-weight-medium d-flex align-center">
|
||
<v-icon start color="success" class="mr-2">mdi-map-marker</v-icon>
|
||
تبدیل کد پستی به آدرس
|
||
</v-card-title>
|
||
|
||
<v-card-text class="pt-4">
|
||
<div class="mb-4">
|
||
<p class="text-body-2 text-medium-emphasis">
|
||
با استفاده از این سرویس میتوانید کد پستی را به آدرس کامل تبدیل کنید.
|
||
</p>
|
||
</div>
|
||
|
||
<v-form ref="postalCodeForm" v-model="postalCodeFormValid">
|
||
<v-text-field v-model="postalCodeData.postalCode" label="کد پستی" placeholder="مثال: 1234567890"
|
||
prepend-inner-icon="mdi-map-marker" variant="outlined" density="comfortable" :rules="[
|
||
v => !!v || 'کد پستی الزامی است',
|
||
v => v.length === 10 || 'کد پستی باید 10 رقم باشد',
|
||
v => /^\d+$/.test(v) || 'کد پستی باید فقط شامل اعداد باشد'
|
||
]" maxlength="10" counter></v-text-field>
|
||
|
||
<v-alert type="info" variant="tonal" class="mt-4">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-information</v-icon>
|
||
</template>
|
||
<div>
|
||
<strong>کارمزد سرویس:</strong> {{ inquirySettings.postalCodeToAddressFee.toLocaleString() }} ریال
|
||
<br>
|
||
<small class="text-caption">
|
||
💡 اگر این کد پستی قبلاً استعلام شده باشد، کارمزدی کسر نمیشود
|
||
</small>
|
||
</div>
|
||
</v-alert>
|
||
|
||
<!-- نمایش خطا -->
|
||
<v-alert v-if="postalCodeError" type="error" variant="tonal" class="mt-4" border="start">
|
||
{{ postalCodeError }}
|
||
</v-alert>
|
||
|
||
<!-- نمایش نتیجه -->
|
||
<v-alert v-if="inquiryResults.postalCode" type="success" variant="tonal" class="mt-4" border="start">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-check-circle</v-icon>
|
||
</template>
|
||
<div>
|
||
<p class="font-weight-medium mb-1">آدرس یافت شده:</p>
|
||
<p class="text-body-2">{{ formatAddress(inquiryResults.postalCode.address) }}</p>
|
||
<p class="text-caption text-medium-emphasis mt-1">
|
||
{{ inquiryResults.postalCode.fromCache ? 'از حافظه موقت' : 'از سرور اصلی' }}
|
||
</p>
|
||
</div>
|
||
</v-alert>
|
||
</v-form>
|
||
</v-card-text>
|
||
|
||
<v-card-actions class="pa-6 pt-0">
|
||
<v-spacer></v-spacer>
|
||
<v-btn variant="outlined" @click="postalCodeDialog = false" :disabled="postalCodeLoading">
|
||
انصراف
|
||
</v-btn>
|
||
<v-btn color="success" @click="submitPostalCodeInquiry" :loading="postalCodeLoading"
|
||
:disabled="!postalCodeFormValid">
|
||
استعلام
|
||
</v-btn>
|
||
</v-card-actions>
|
||
</v-card>
|
||
</v-dialog>
|
||
|
||
<!-- دیالوگ تبدیل شماره کارت به شبا -->
|
||
<v-dialog v-model="cardToShebaDialog" max-width="500px" persistent>
|
||
<v-card>
|
||
<v-card-title class="text-h6 font-weight-medium d-flex align-center">
|
||
<v-icon start color="info" class="mr-2">mdi-credit-card</v-icon>
|
||
تبدیل شماره کارت به شبا
|
||
</v-card-title>
|
||
|
||
<v-card-text class="pt-4">
|
||
<v-form ref="cardToShebaForm" v-model="cardToShebaFormValid">
|
||
<v-text-field v-model="cardToShebaData.cardNumber" label="شماره کارت" placeholder="مثال: 6037991234567890"
|
||
prepend-inner-icon="mdi-credit-card" variant="outlined" density="comfortable" :rules="[
|
||
v => !!v || 'شماره کارت الزامی است',
|
||
v => v.length === 16 || 'شماره کارت باید 16 رقم باشد',
|
||
v => /^\d+$/.test(v) || 'شماره کارت باید فقط شامل اعداد باشد'
|
||
]" maxlength="16" counter></v-text-field>
|
||
|
||
<v-alert type="info" variant="tonal" class="mt-4">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-information</v-icon>
|
||
</template>
|
||
<div>
|
||
<strong>کارمزد سرویس:</strong> {{ inquirySettings.cardToShebaFee.toLocaleString() }} ریال
|
||
<br>
|
||
<small class="text-caption">
|
||
💡 اگر این شماره کارت قبلاً استعلام شده باشد، کارمزدی کسر نمیشود
|
||
</small>
|
||
</div>
|
||
</v-alert>
|
||
|
||
<!-- نمایش خطا -->
|
||
<v-alert v-if="cardToShebaError" type="error" variant="tonal" class="mt-4" border="start">
|
||
{{ cardToShebaError }}
|
||
</v-alert>
|
||
|
||
<!-- نمایش نتیجه -->
|
||
<v-alert v-if="inquiryResults.cardToSheba" type="success" variant="tonal" class="mt-4" border="start">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-check-circle</v-icon>
|
||
</template>
|
||
<div>
|
||
<p class="font-weight-medium mb-2">اطلاعات کارت:</p>
|
||
<div class="mb-2">
|
||
<strong>شماره شبا:</strong>
|
||
<span class="font-family-monospace">{{ inquiryResults.cardToSheba.IBAN }}</span>
|
||
</div>
|
||
<div class="mb-2">
|
||
<strong>نام صاحب کارت:</strong>
|
||
<span>{{ inquiryResults.cardToSheba.name }}</span>
|
||
</div>
|
||
<div class="mb-2">
|
||
<strong>نام بانک:</strong>
|
||
<span>{{ inquiryResults.cardToSheba.bank_name }}</span>
|
||
</div>
|
||
<p class="text-caption text-medium-emphasis mt-2">
|
||
{{ inquiryResults.cardToSheba.fromCache ? 'از حافظه موقت' : 'از سرور اصلی' }}
|
||
</p>
|
||
</div>
|
||
</v-alert>
|
||
</v-form>
|
||
</v-card-text>
|
||
|
||
<v-card-actions class="pa-6 pt-0">
|
||
<v-spacer></v-spacer>
|
||
<v-btn variant="outlined" @click="cardToShebaDialog = false" :disabled="cardToShebaLoading">
|
||
انصراف
|
||
</v-btn>
|
||
<v-btn color="info" @click="submitCardToShebaInquiry" :loading="cardToShebaLoading"
|
||
:disabled="!cardToShebaFormValid">
|
||
استعلام
|
||
</v-btn>
|
||
</v-card-actions>
|
||
</v-card>
|
||
</v-dialog>
|
||
|
||
<!-- دیالوگ تبدیل حساب به شبا -->
|
||
<v-dialog v-model="accountToShebaDialog" max-width="500px" persistent>
|
||
<v-card>
|
||
<v-card-title class="text-h6 font-weight-medium d-flex align-center">
|
||
<v-icon start color="warning" class="mr-2">mdi-bank</v-icon>
|
||
تبدیل حساب به شبا
|
||
</v-card-title>
|
||
|
||
<v-card-text class="pt-4">
|
||
<v-form ref="accountToShebaForm" v-model="accountToShebaFormValid">
|
||
<v-select v-model="accountToShebaData.bankCode" label="کد بانک" placeholder="انتخاب کنید"
|
||
prepend-inner-icon="mdi-bank" variant="outlined" density="comfortable" :items="bankCodes" item-title="name"
|
||
item-value="code" :rules="[
|
||
v => !!v || 'کد بانک الزامی است'
|
||
]"></v-select>
|
||
|
||
<v-text-field v-model="accountToShebaData.accountNumber" label="شماره حساب"
|
||
placeholder="مثال: 4600000123456789" prepend-inner-icon="mdi-account" variant="outlined"
|
||
density="comfortable" class="mt-4" :rules="[
|
||
v => !!v || 'شماره حساب الزامی است',
|
||
v => v.length >= 10 || 'شماره حساب باید حداقل 10 رقم باشد',
|
||
v => /^\d+$/.test(v) || 'شماره حساب باید فقط شامل اعداد باشد'
|
||
]" maxlength="20" counter></v-text-field>
|
||
|
||
<v-alert type="info" variant="tonal" class="mt-4">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-information</v-icon>
|
||
</template>
|
||
<div>
|
||
<strong>کارمزد سرویس:</strong> {{ inquirySettings.accountToShebaFee.toLocaleString() }} ریال
|
||
<br>
|
||
<small class="text-caption">
|
||
💡 اگر این حساب قبلاً استعلام شده باشد، کارمزدی کسر نمیشود
|
||
</small>
|
||
</div>
|
||
</v-alert>
|
||
|
||
<!-- نمایش خطا -->
|
||
<v-alert v-if="accountToShebaError" type="error" variant="tonal" class="mt-4" border="start">
|
||
{{ accountToShebaError }}
|
||
</v-alert>
|
||
|
||
<!-- نمایش نتیجه -->
|
||
<v-alert v-if="inquiryResults.accountToSheba" type="success" variant="tonal" class="mt-4" border="start">
|
||
<template v-slot:prepend>
|
||
<v-icon>mdi-check-circle</v-icon>
|
||
</template>
|
||
<div>
|
||
<p class="font-weight-medium mb-2">اطلاعات حساب:</p>
|
||
<div class="mb-2">
|
||
<strong>شماره شبا:</strong>
|
||
<span class="font-family-monospace">{{ inquiryResults.accountToSheba.IBAN }}</span>
|
||
</div>
|
||
<p class="text-caption text-medium-emphasis mt-2">
|
||
{{ inquiryResults.accountToSheba.fromCache ? 'از حافظه موقت' : 'از سرور اصلی' }}
|
||
</p>
|
||
</div>
|
||
</v-alert>
|
||
</v-form>
|
||
</v-card-text>
|
||
|
||
<v-card-actions class="pa-6 pt-0">
|
||
<v-spacer></v-spacer>
|
||
<v-btn variant="outlined" @click="accountToShebaDialog = false" :disabled="accountToShebaLoading">
|
||
انصراف
|
||
</v-btn>
|
||
<v-btn color="warning" @click="submitAccountToShebaInquiry" :loading="accountToShebaLoading"
|
||
:disabled="!accountToShebaFormValid">
|
||
استعلام
|
||
</v-btn>
|
||
</v-card-actions>
|
||
</v-card>
|
||
</v-dialog>
|
||
|
||
<!-- Snackbar برای نمایش پیامها -->
|
||
<v-snackbar v-model="snackbar.show" :color="snackbar.color" :timeout="snackbar.timeout" location="bottom">
|
||
{{ snackbar.text }}
|
||
|
||
<template v-slot:actions>
|
||
<v-btn color="white" variant="text" @click="snackbar.show = false">
|
||
بستن
|
||
</v-btn>
|
||
</template>
|
||
</v-snackbar>
|
||
</template>
|
||
|
||
<script>
|
||
import axios from "axios";
|
||
|
||
export default {
|
||
name: 'panel',
|
||
data() {
|
||
return {
|
||
loading: true,
|
||
businessInfo: {
|
||
smsCharge: 0
|
||
},
|
||
inquirySettings: {
|
||
enablePostalCodeToAddress: false,
|
||
postalCodeToAddressFee: 0,
|
||
enableCardToSheba: false,
|
||
cardToShebaFee: 0,
|
||
enableAccountToSheba: false,
|
||
accountToShebaFee: 0,
|
||
},
|
||
|
||
// دیالوگها
|
||
postalCodeDialog: false,
|
||
cardToShebaDialog: false,
|
||
accountToShebaDialog: false,
|
||
|
||
// فرمها
|
||
postalCodeFormValid: false,
|
||
cardToShebaFormValid: false,
|
||
accountToShebaFormValid: false,
|
||
|
||
// دادههای فرم
|
||
postalCodeData: {
|
||
postalCode: ''
|
||
},
|
||
cardToShebaData: {
|
||
cardNumber: ''
|
||
},
|
||
accountToShebaData: {
|
||
bankCode: '',
|
||
accountNumber: ''
|
||
},
|
||
|
||
// وضعیت لودینگ
|
||
postalCodeLoading: false,
|
||
cardToShebaLoading: false,
|
||
accountToShebaLoading: false,
|
||
|
||
// خطاها
|
||
postalCodeError: null,
|
||
cardToShebaError: null,
|
||
accountToShebaError: null,
|
||
|
||
// Snackbar
|
||
snackbar: {
|
||
show: false,
|
||
text: '',
|
||
color: 'success',
|
||
timeout: 3000
|
||
},
|
||
|
||
// نتایج استعلام
|
||
inquiryResults: {
|
||
postalCode: null,
|
||
cardToSheba: null,
|
||
accountToSheba: null
|
||
}
|
||
}
|
||
},
|
||
computed: {
|
||
hasActiveServices() {
|
||
return this.inquirySettings.enablePostalCodeToAddress ||
|
||
this.inquirySettings.enableCardToSheba ||
|
||
this.inquirySettings.enableAccountToSheba;
|
||
},
|
||
|
||
hasLowCredit() {
|
||
const minCredit = Math.min(
|
||
this.inquirySettings.postalCodeToAddressFee,
|
||
this.inquirySettings.cardToShebaFee,
|
||
this.inquirySettings.accountToShebaFee
|
||
);
|
||
return (this.businessInfo.smsCharge || 0) < minCredit;
|
||
},
|
||
|
||
bankCodes() {
|
||
return [
|
||
{ code: '066', name: 'دی' },
|
||
{ code: '015', name: 'سپه' },
|
||
{ code: '061', name: 'شهر' },
|
||
{ code: '012', name: 'ملت' },
|
||
{ code: '017', name: 'ملی' },
|
||
{ code: '013', name: 'رفاه' },
|
||
{ code: '059', name: 'سینا' },
|
||
{ code: '014', name: 'مسکن' },
|
||
{ code: '062', name: 'آینده' },
|
||
{ code: '063', name: 'انصار' },
|
||
{ code: '018', name: 'تجارت' },
|
||
{ code: '070', name: 'رسالت' },
|
||
{ code: '056', name: 'سامان' },
|
||
{ code: '010', name: 'مرکزی' },
|
||
{ code: '058', name: 'سرمایه' },
|
||
{ code: '019', name: 'صادرات' },
|
||
{ code: '052', name: 'قوامین' },
|
||
{ code: '054', name: 'پارسیان' },
|
||
{ code: '016', name: 'کشاورزی' },
|
||
{ code: '064', name: 'گردشگری' },
|
||
{ code: '021', name: 'پست بانک' },
|
||
{ code: '057', name: 'پاسارگاد' },
|
||
{ code: '053', name: 'کارآفرین' },
|
||
{ code: '078', name: 'خاورمیانه' },
|
||
{ code: '069', name: 'ایران زمین' },
|
||
{ code: '079', name: 'مهر اقتصاد' },
|
||
{ code: '011', name: 'صنعت و معدن' },
|
||
{ code: '055', name: 'اقتصاد نوین' },
|
||
{ code: '022', name: 'توسعه تعاون' },
|
||
{ code: '020', name: 'توسعه صادرات' },
|
||
{ code: '095', name: 'ایران-ونزوئلا' },
|
||
{ code: '065', name: 'حکمت ایرانیان' },
|
||
{ code: '060', name: 'قرض الحسنه مهر' },
|
||
{ code: '075', name: 'موسسه اعتباری ملل' },
|
||
{ code: '080', name: 'موسسه اعتباری نور' },
|
||
{ code: '073', name: 'موسسه اعتباری کوثر' },
|
||
{ code: '051', name: 'موسسه اعتباری توسعه' }
|
||
];
|
||
}
|
||
},
|
||
methods: {
|
||
// نمایش Snackbar
|
||
showSnackbar(text, color = 'success', timeout = 3000) {
|
||
this.snackbar = {
|
||
show: true,
|
||
text,
|
||
color,
|
||
timeout
|
||
};
|
||
},
|
||
|
||
// فرمت کردن آبجکت آدرس به رشته خوانا
|
||
formatAddress(addressObj) {
|
||
if (!addressObj || typeof addressObj !== 'object') return '';
|
||
const parts = [];
|
||
if (addressObj.province) parts.push(addressObj.province);
|
||
if (addressObj.town) parts.push(addressObj.town);
|
||
if (addressObj.street2) parts.push(addressObj.street2);
|
||
if (addressObj.street) parts.push(addressObj.street);
|
||
if (addressObj.district) parts.push('محله ' + addressObj.district);
|
||
if (addressObj.building_name) parts.push('ساختمان ' + addressObj.building_name);
|
||
if (addressObj.number) parts.push('پلاک ' + addressObj.number);
|
||
if (addressObj.floor) parts.push('طبقه ' + addressObj.floor);
|
||
if (addressObj.side_floor) parts.push('واحد ' + addressObj.side_floor);
|
||
if (addressObj.description) parts.push(addressObj.description);
|
||
return parts.join('، ');
|
||
},
|
||
|
||
// فرمت کردن عدد به ریال
|
||
formatCurrency(number) {
|
||
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||
},
|
||
|
||
// تعیین رنگ کارت اعتبار بر اساس میزان اعتبار
|
||
getCreditCardColor() {
|
||
if (this.hasLowCredit) {
|
||
return 'error';
|
||
} else if ((this.businessInfo.smsCharge || 0) > 100000) {
|
||
return 'success';
|
||
} else {
|
||
return 'primary';
|
||
}
|
||
},
|
||
|
||
// تعیین رنگ وضعیت اعتبار
|
||
getCreditStatusColor() {
|
||
if (this.hasLowCredit) {
|
||
return 'error';
|
||
} else if ((this.businessInfo.smsCharge || 0) > 100000) {
|
||
return 'success';
|
||
} else {
|
||
return 'warning';
|
||
}
|
||
},
|
||
|
||
// تعیین آیکون وضعیت اعتبار
|
||
getCreditStatusIcon() {
|
||
if (this.hasLowCredit) {
|
||
return 'mdi-alert';
|
||
} else if ((this.businessInfo.smsCharge || 0) > 100000) {
|
||
return 'mdi-check-circle';
|
||
} else {
|
||
return 'mdi-information';
|
||
}
|
||
},
|
||
|
||
// تعیین متن وضعیت اعتبار
|
||
getCreditStatusText() {
|
||
if (this.hasLowCredit) {
|
||
return 'اعتبار کم';
|
||
} else if ((this.businessInfo.smsCharge || 0) > 100000) {
|
||
return 'اعتبار کافی';
|
||
} else {
|
||
return 'اعتبار متوسط';
|
||
}
|
||
},
|
||
|
||
// تعیین متن کوتاه وضعیت اعتبار برای موبایل
|
||
getCreditStatusTextShort() {
|
||
if (this.hasLowCredit) {
|
||
return 'کم';
|
||
} else if ((this.businessInfo.smsCharge || 0) > 100000) {
|
||
return 'کافی';
|
||
} else {
|
||
return 'متوسط';
|
||
}
|
||
},
|
||
|
||
// بارگذاری تنظیمات استعلامات
|
||
async loadInquirySettings() {
|
||
try {
|
||
this.loading = true;
|
||
const response = await axios.get('/api/plugins/inquiry/settings/get');
|
||
this.inquirySettings = {
|
||
enablePostalCodeToAddress: response.data.enablePostalCodeToAddress === '1' || response.data.enablePostalCodeToAddress === true,
|
||
postalCodeToAddressFee: parseInt(response.data.postalCodeToAddressFee) || 0,
|
||
enableCardToSheba: response.data.enableCardToSheba === '1' || response.data.enableCardToSheba === true,
|
||
cardToShebaFee: parseInt(response.data.cardToShebaFee) || 0,
|
||
enableAccountToSheba: response.data.enableAccountToSheba === '1' || response.data.enableAccountToSheba === true,
|
||
accountToShebaFee: parseInt(response.data.accountToShebaFee) || 0,
|
||
};
|
||
} catch (error) {
|
||
console.error('خطا در بارگذاری تنظیمات استعلامات:', error);
|
||
this.showSnackbar('خطا در بارگذاری تنظیمات استعلامات', 'error');
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
// بارگذاری اطلاعات کسب و کار
|
||
async loadBusinessInfo() {
|
||
try {
|
||
const activeBid = localStorage.getItem('activeBid');
|
||
if (!activeBid) {
|
||
console.error('شناسه کسب و کار فعال یافت نشد');
|
||
return;
|
||
}
|
||
|
||
const response = await axios.get(`/api/business/get/info/${activeBid}`);
|
||
this.businessInfo = response.data;
|
||
} catch (error) {
|
||
console.error('خطا در بارگذاری اطلاعات کسب و کار:', error);
|
||
this.showSnackbar('خطا در بارگذاری اطلاعات کسب و کار', 'error');
|
||
}
|
||
},
|
||
|
||
// باز کردن دیالوگ کد پستی
|
||
openPostalCodeDialog() {
|
||
this.postalCodeData.postalCode = '';
|
||
this.postalCodeError = null;
|
||
this.inquiryResults.postalCode = null; // Clear previous result
|
||
this.postalCodeDialog = true;
|
||
},
|
||
|
||
// باز کردن دیالوگ کارت به شبا
|
||
openCardToShebaDialog() {
|
||
this.cardToShebaData.cardNumber = '';
|
||
this.cardToShebaError = null;
|
||
this.inquiryResults.cardToSheba = null; // Clear previous result
|
||
this.cardToShebaDialog = true;
|
||
},
|
||
|
||
// باز کردن دیالوگ حساب به شبا
|
||
openAccountToShebaDialog() {
|
||
this.accountToShebaData.bankCode = '';
|
||
this.accountToShebaData.accountNumber = '';
|
||
this.accountToShebaError = null;
|
||
this.inquiryResults.accountToSheba = null; // Clear previous result
|
||
this.accountToShebaDialog = true;
|
||
},
|
||
|
||
// ارسال استعلام کد پستی
|
||
async submitPostalCodeInquiry() {
|
||
if (!this.$refs.postalCodeForm.validate()) return;
|
||
|
||
// بررسی اعتبار کافی
|
||
if ((this.businessInfo.smsCharge || 0) < this.inquirySettings.postalCodeToAddressFee) {
|
||
this.showSnackbar('اعتبار شما برای این استعلام کافی نیست. لطفاً اعتبار خود را افزایش دهید.', 'error');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.postalCodeLoading = true;
|
||
this.postalCodeError = null;
|
||
|
||
const response = await axios.post('/api/plugins/inquiry/postalcode-to-address', {
|
||
postal_code: this.postalCodeData.postalCode
|
||
});
|
||
|
||
if (response.data.success) {
|
||
// نمایش پیام مناسب بر اساس منبع داده
|
||
const message = response.data.from_cache
|
||
? 'اطلاعات آدرس از حافظه موقت دریافت شد (بدون کسر کارمزد)'
|
||
: 'اطلاعات آدرس با موفقیت دریافت شد';
|
||
// ذخیره نتیجه
|
||
this.inquiryResults.postalCode = {
|
||
postalCode: this.postalCodeData.postalCode,
|
||
address: response.data.data,
|
||
fromCache: response.data.from_cache,
|
||
message: response.data.message
|
||
};
|
||
this.showSnackbar(message, 'success');
|
||
// بهروزرسانی اعتبار کاربر
|
||
if (!response.data.from_cache) {
|
||
this.businessInfo.smsCharge = Math.max(0, (this.businessInfo.smsCharge || 0) - this.inquirySettings.postalCodeToAddressFee);
|
||
}
|
||
// this.postalCodeDialog = false; // حذف بستن دیالوگ
|
||
} else {
|
||
// مدیریت خطاهای خاص
|
||
let errorMessage = response.data.message || 'خطا در استعلام';
|
||
if (response.data.error_code === 'HTTP_ERROR_504') {
|
||
errorMessage = 'سرویس استعلام کد پستی در دسترس نیست. لطفاً بعداً تلاش کنید.';
|
||
}
|
||
|
||
this.postalCodeError = errorMessage;
|
||
this.showSnackbar(errorMessage, 'error');
|
||
}
|
||
} catch (error) {
|
||
console.error('خطا در استعلام کد پستی:', error);
|
||
this.postalCodeError = 'خطا در برقراری ارتباط با سرور';
|
||
this.showSnackbar('خطا در برقراری ارتباط با سرور', 'error');
|
||
} finally {
|
||
this.postalCodeLoading = false;
|
||
}
|
||
},
|
||
|
||
// ارسال استعلام کارت به شبا
|
||
async submitCardToShebaInquiry() {
|
||
if (!this.$refs.cardToShebaForm.validate()) return;
|
||
|
||
// بررسی اعتبار کافی
|
||
if ((this.businessInfo.smsCharge || 0) < this.inquirySettings.cardToShebaFee) {
|
||
this.showSnackbar('اعتبار شما برای این استعلام کافی نیست. لطفاً اعتبار خود را افزایش دهید.', 'error');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.cardToShebaLoading = true;
|
||
this.cardToShebaError = null;
|
||
|
||
const response = await axios.post('/api/plugins/inquiry/card-to-sheba', {
|
||
card_number: this.cardToShebaData.cardNumber
|
||
});
|
||
|
||
if (response.data.success) {
|
||
// نمایش پیام مناسب بر اساس منبع داده
|
||
const message = response.data.from_cache
|
||
? 'اطلاعات کارت از حافظه موقت دریافت شد (بدون کسر کارمزد)'
|
||
: 'اطلاعات کارت با موفقیت دریافت شد';
|
||
|
||
// ذخیره نتیجه
|
||
this.inquiryResults.cardToSheba = {
|
||
cardNumber: this.cardToShebaData.cardNumber,
|
||
IBAN: response.data.data.IBAN,
|
||
name: response.data.data.name,
|
||
bank_name: response.data.data.bank_name,
|
||
fromCache: response.data.from_cache,
|
||
message: response.data.message
|
||
};
|
||
|
||
this.showSnackbar(message, 'success');
|
||
// بهروزرسانی اعتبار کاربر
|
||
if (!response.data.from_cache) {
|
||
this.businessInfo.smsCharge = Math.max(0, (this.businessInfo.smsCharge || 0) - this.inquirySettings.cardToShebaFee);
|
||
}
|
||
// this.cardToShebaDialog = false; // حذف بستن دیالوگ
|
||
} else {
|
||
// مدیریت خطاهای خاص
|
||
let errorMessage = response.data.message || 'خطا در استعلام';
|
||
|
||
// تبدیل کدهای خطا به پیامهای فارسی
|
||
if (response.data.error_code) {
|
||
switch (response.data.error_code) {
|
||
case 'CARD_LOST':
|
||
errorMessage = 'کارت گم شده است';
|
||
break;
|
||
case 'CARD_EXPIRED':
|
||
errorMessage = 'کارت منقضی شده است';
|
||
break;
|
||
case 'CARD_NOT_FOUND':
|
||
errorMessage = 'کارت وارد شده در سیستم بانکی وجود ندارد';
|
||
break;
|
||
case 'CARD_NOT_ACTIVE':
|
||
errorMessage = 'کارت غیر فعال است';
|
||
break;
|
||
case 'ACCOUNT_NOT_ACTIVE':
|
||
errorMessage = 'حساب متصل به کارت فعال نیست';
|
||
break;
|
||
case 'CARD_NUMBER_NOT_VALID':
|
||
errorMessage = 'شماره کارت نامعتبر است';
|
||
break;
|
||
}
|
||
}
|
||
|
||
this.cardToShebaError = errorMessage;
|
||
this.showSnackbar(errorMessage, 'error');
|
||
}
|
||
} catch (error) {
|
||
console.error('خطا در استعلام کارت به شبا:', error);
|
||
this.cardToShebaError = 'خطا در برقراری ارتباط با سرور';
|
||
this.showSnackbar('خطا در برقراری ارتباط با سرور', 'error');
|
||
} finally {
|
||
this.cardToShebaLoading = false;
|
||
}
|
||
},
|
||
|
||
// ارسال استعلام حساب به شبا
|
||
async submitAccountToShebaInquiry() {
|
||
if (!this.$refs.accountToShebaForm.validate()) return;
|
||
|
||
// بررسی اعتبار کافی
|
||
if ((this.businessInfo.smsCharge || 0) < this.inquirySettings.accountToShebaFee) {
|
||
this.showSnackbar('اعتبار شما برای این استعلام کافی نیست. لطفاً اعتبار خود را افزایش دهید.', 'error');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
this.accountToShebaLoading = true;
|
||
this.accountToShebaError = null;
|
||
|
||
const response = await axios.post('/api/plugins/inquiry/account-to-sheba', {
|
||
bank_code: this.accountToShebaData.bankCode,
|
||
account_number: this.accountToShebaData.accountNumber
|
||
});
|
||
|
||
if (response.data.success) {
|
||
// نمایش پیام مناسب بر اساس منبع داده
|
||
const message = response.data.from_cache
|
||
? 'اطلاعات حساب از حافظه موقت دریافت شد (بدون کسر کارمزد)'
|
||
: 'اطلاعات حساب با موفقیت دریافت شد';
|
||
|
||
// ذخیره نتیجه
|
||
this.inquiryResults.accountToSheba = {
|
||
bankCode: this.accountToShebaData.bankCode,
|
||
accountNumber: this.accountToShebaData.accountNumber,
|
||
IBAN: response.data.data.IBAN,
|
||
fromCache: response.data.from_cache,
|
||
message: response.data.message
|
||
};
|
||
|
||
this.showSnackbar(message, 'success');
|
||
// بهروزرسانی اعتبار کاربر
|
||
if (!response.data.from_cache) {
|
||
this.businessInfo.smsCharge = Math.max(0, (this.businessInfo.smsCharge || 0) - this.inquirySettings.accountToShebaFee);
|
||
}
|
||
// this.accountToShebaDialog = false; // حذف بستن دیالوگ
|
||
} else {
|
||
// مدیریت خطاهای خاص
|
||
let errorMessage = response.data.message || 'خطا در استعلام';
|
||
|
||
// تبدیل کدهای خطا به پیامهای فارسی
|
||
if (response.data.error_code) {
|
||
switch (response.data.error_code) {
|
||
case 'ACCOUNT_NOT_ACTIVE':
|
||
errorMessage = 'حساب غیر فعال است';
|
||
break;
|
||
}
|
||
}
|
||
|
||
this.accountToShebaError = errorMessage;
|
||
this.showSnackbar(errorMessage, 'error');
|
||
}
|
||
} catch (error) {
|
||
console.error('خطا در استعلام حساب به شبا:', error);
|
||
this.accountToShebaError = 'خطا در برقراری ارتباط با سرور';
|
||
this.showSnackbar('خطا در برقراری ارتباط با سرور', 'error');
|
||
} finally {
|
||
this.accountToShebaLoading = false;
|
||
}
|
||
},
|
||
},
|
||
|
||
async mounted() {
|
||
await this.loadInquirySettings();
|
||
await this.loadBusinessInfo();
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* کارت اعتبار */
|
||
.credit-card {
|
||
position: relative;
|
||
overflow: hidden;
|
||
border-radius: 16px !important;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.credit-card:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15) !important;
|
||
}
|
||
|
||
.credit-card-background {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 0;
|
||
}
|
||
|
||
.credit-card-pattern {
|
||
position: absolute;
|
||
top: -50%;
|
||
right: -50%;
|
||
width: 200%;
|
||
height: 200%;
|
||
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 1px, transparent 1px);
|
||
background-size: 20px 20px;
|
||
animation: float 6s ease-in-out infinite;
|
||
}
|
||
|
||
@keyframes float {
|
||
|
||
0%,
|
||
100% {
|
||
transform: translateY(0px) rotate(0deg);
|
||
}
|
||
|
||
50% {
|
||
transform: translateY(-10px) rotate(180deg);
|
||
}
|
||
}
|
||
|
||
.credit-card-primary {
|
||
background: linear-gradient(135deg, #1976d2 0%, #42a5f5 100%);
|
||
}
|
||
|
||
.credit-card-success {
|
||
background: linear-gradient(135deg, #2e7d32 0%, #66bb6a 100%);
|
||
}
|
||
|
||
.credit-card-error {
|
||
background: linear-gradient(135deg, #d32f2f 0%, #ef5350 100%);
|
||
}
|
||
|
||
.credit-icon-wrapper {
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 50%;
|
||
padding: 12px;
|
||
backdrop-filter: blur(10px);
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
}
|
||
|
||
.add-credit-btn {
|
||
backdrop-filter: blur(10px);
|
||
border: 2px solid rgba(255, 255, 255, 0.3) !important;
|
||
font-weight: 600;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.add-credit-btn:hover {
|
||
background: rgba(255, 255, 255, 0.1) !important;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
.credit-amount-section {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.credit-amount-display {
|
||
flex: 1;
|
||
}
|
||
|
||
.amount-label {
|
||
font-size: 14px;
|
||
color: rgba(255, 255, 255, 0.8);
|
||
margin-bottom: 8px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.amount-value {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 12px;
|
||
}
|
||
|
||
.currency-symbol {
|
||
font-size: 18px;
|
||
color: rgba(255, 255, 255, 0.9);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.amount-number {
|
||
font-size: 32px;
|
||
font-weight: 700;
|
||
color: white;
|
||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||
font-family: 'Courier New', monospace;
|
||
}
|
||
|
||
.credit-status-indicator {
|
||
text-align: right;
|
||
}
|
||
|
||
.status-chip {
|
||
backdrop-filter: blur(10px);
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.credit-alert {
|
||
backdrop-filter: blur(10px);
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
background: rgba(255, 255, 255, 0.1) !important;
|
||
}
|
||
|
||
/* کارتهای سرویس */
|
||
.service-card {
|
||
transition: all 0.3s ease;
|
||
border: 2px solid transparent;
|
||
position: relative;
|
||
overflow: hidden;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.service-card:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1) !important;
|
||
}
|
||
|
||
.service-card-header {
|
||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||
position: relative;
|
||
}
|
||
|
||
.service-card-header::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 1px;
|
||
background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.1), transparent);
|
||
}
|
||
|
||
/* انیمیشن برای chip ها */
|
||
.v-chip {
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.v-chip:hover {
|
||
transform: scale(1.05);
|
||
}
|
||
|
||
/* استایل برای آیکونها */
|
||
.service-card .v-icon {
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.service-card:hover .v-icon {
|
||
transform: scale(1.1);
|
||
}
|
||
|
||
/* استایل برای دکمهها */
|
||
.v-btn {
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.v-btn:hover {
|
||
transform: translateY(-1px);
|
||
}
|
||
|
||
/* ریسپانسیو */
|
||
@media (max-width: 768px) {
|
||
.credit-amount-section {
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 16px;
|
||
}
|
||
|
||
.credit-status-indicator {
|
||
text-align: left;
|
||
}
|
||
|
||
.amount-number {
|
||
font-size: 24px;
|
||
}
|
||
|
||
.currency-symbol {
|
||
font-size: 16px;
|
||
}
|
||
|
||
.credit-card .v-card-text {
|
||
padding: 20px !important;
|
||
}
|
||
|
||
.credit-icon-wrapper {
|
||
padding: 8px;
|
||
}
|
||
|
||
.credit-icon-wrapper .v-icon {
|
||
font-size: 32px !important;
|
||
}
|
||
|
||
.add-credit-btn {
|
||
width: 100%;
|
||
max-width: 200px;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.amount-number {
|
||
font-size: 20px;
|
||
}
|
||
|
||
.currency-symbol {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.credit-card .v-card-text {
|
||
padding: 16px !important;
|
||
}
|
||
|
||
.amount-value {
|
||
gap: 8px;
|
||
}
|
||
}
|
||
</style>
|