hesabixCore/webUI/src/views/acc/settings/tax-settings.vue

321 lines
11 KiB
Vue

<template>
<div>
<v-toolbar color="toolbar" title="تنظیمات مالیاتی">
<template v-slot:prepend>
<v-tooltip text="بازگشت" 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-spacer></v-spacer>
<v-btn :loading="loading" @click="saveSettings()" icon="" color="green">
<v-tooltip activator="parent" text="ذخیره تنظیمات" location="bottom" />
<v-icon icon="mdi-content-save"></v-icon>
</v-btn>
</v-toolbar>
<v-container>
<v-card :loading="loading" :disabled="loading">
<v-card-text>
<v-row>
<v-col cols="12" md="6">
<v-btn
color="primary"
@click="showCSRDialog = true"
prepend-icon="mdi-key-plus"
>
ساخت کلید و CSR
</v-btn>
</v-col>
<v-col cols="12" md="6">
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="settings.taxMemoryId"
label="شناسه یکتای حافظه مالیاتی"
hide-details
density="compact"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="settings.economicCode"
label="کد اقتصادی"
hide-details
density="compact"
></v-text-field>
</v-col>
</v-row>
</v-col>
</v-row>
<v-row class="mt-4">
<v-col cols="12">
<v-textarea
v-model="settings.privateKey"
label="Private Key"
rows="15"
variant="outlined"
hide-details
placeholder="کلید خصوصی اینجا قرار می‌گیرد..."
></v-textarea>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-container>
<!-- Dialog برای ساخت کلید و CSR -->
<v-dialog v-model="showCSRDialog" max-width="600px">
<v-card>
<v-card-title class="text-h6">
ساخت کلید و CSR
</v-card-title>
<v-card-text>
<v-form ref="csrForm">
<div class="mb-4">
<div class="text-subtitle-2 mb-2">شخص</div>
<v-radio-group
v-model="csrData.personType"
inline
hide-details
>
<v-radio
v-for="type in personTypes"
:key="type.value"
:label="type.title"
:value="type.value"
:disabled="type.value === 'natural'"
></v-radio>
</v-radio-group>
</div>
<v-text-field
v-model="csrData.nationalId"
label="شناسه ملی"
hide-details
class="mb-4"
></v-text-field>
<v-text-field
v-model="csrData.nameFa"
label="نام (فارسی)"
hide-details
class="mb-4"
></v-text-field>
<v-text-field
v-model="csrData.nameEn"
label="نام (انگلیسی)"
hide-details
class="mb-4"
></v-text-field>
<v-text-field
v-model="csrData.email"
label="ایمیل"
type="email"
hide-details
class="mb-4"
></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="showCSRDialog = false" variant="text">
انصراف
</v-btn>
<v-btn @click="generateCSR()" color="primary" :loading="csrLoading">
تایید
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-dialog v-model="showResultDialog" max-width="900px">
<v-card>
<v-card-title class="text-h6 pb-0">ساخت کلید و CSR</v-card-title>
<v-card-text>
<v-alert type="info" color="blue" class="mb-4" icon="mdi-alert">
<span class="font-weight-bold">توجه: لطفا این اطلاعات را دانلود کنید و در یک جای امن نگهداری کنید. به دلایل امنیتی اطلاعات شما را نگهداری نمی‌کنیم، در صورتی که این اطلاعات را گم کنید، امکان بازیابی آن وجود ندارد.</span>
</v-alert>
<v-row>
<v-col cols="12" md="4">
<div class="mb-2 font-weight-bold">CSR</div>
<v-textarea readonly rows="10" :value="resultData.csr" variant="outlined"></v-textarea>
<v-row class="mt-2">
<v-col cols="6">
<v-btn color="success" block @click="copyToClipboard(resultData.csr)"><v-icon start>mdi-content-copy</v-icon>کپی</v-btn>
</v-col>
<v-col cols="6">
<v-btn color="success" block @click="downloadFile(resultData.csr, 'csr.txt')"><v-icon start>mdi-download</v-icon>دانلود</v-btn>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="4">
<div class="mb-2 font-weight-bold">Public Key</div>
<v-textarea readonly rows="10" :value="resultData.publicKey" variant="outlined"></v-textarea>
<v-row class="mt-2">
<v-col cols="6">
<v-btn color="success" block @click="copyToClipboard(resultData.publicKey)"><v-icon start>mdi-content-copy</v-icon>کپی</v-btn>
</v-col>
<v-col cols="6">
<v-btn color="success" block @click="downloadFile(resultData.publicKey, 'public_key.txt')"><v-icon start>mdi-download</v-icon>دانلود</v-btn>
</v-col>
</v-row>
</v-col>
<v-col cols="12" md="4">
<div class="mb-2 font-weight-bold">Private Key</div>
<v-textarea readonly rows="10" :value="resultData.privateKey" variant="outlined"></v-textarea>
<v-row class="mt-2">
<v-col cols="6">
<v-btn color="success" block @click="copyToClipboard(resultData.privateKey)"><v-icon start>mdi-content-copy</v-icon>کپی</v-btn>
</v-col>
<v-col cols="6">
<v-btn color="success" block @click="downloadFile(resultData.privateKey, 'private_key.txt')"><v-icon start>mdi-download</v-icon>دانلود</v-btn>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="showResultDialog = false" color="primary">بستن</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar
v-model="snackbar.show"
:color="snackbar.color"
:timeout="3000"
>
{{ snackbar.text }}
<template v-slot:actions>
<v-btn
color="white"
variant="text"
@click="snackbar.show = false"
>
بستن
</v-btn>
</template>
</v-snackbar>
</div>
</template>
<script>
import axios from 'axios';
import Swal from 'sweetalert2';
export default {
name: 'TaxSettings',
data: () => ({
loading: false,
csrLoading: false,
showCSRDialog: false,
showResultDialog: false,
settings: {
taxMemoryId: '',
economicCode: '',
privateKey: '',
},
csrData: {
personType: 'legal',
nationalId: '',
nameFa: '',
nameEn: '',
email: '',
},
resultData: {
csr: '',
publicKey: '',
privateKey: ''
},
personTypes: [
{ title: 'حقیقی', value: 'natural' },
{ title: 'حقوقی', value: 'legal' }
],
snackbar: {
show: false,
text: '',
color: 'success'
}
}),
methods: {
async loadSettings() {
this.loading = true;
try {
const response = await axios.get('/api/plugins/tax-settings/get');
this.settings = {
...this.settings,
...response.data
};
} catch (error) {
this.showSnackbar('خطا در بارگذاری تنظیمات', 'error');
} finally {
this.loading = false;
}
},
async saveSettings() {
this.loading = true;
try {
const dataToSave = { ...this.settings };
await axios.post('/api/plugins/tax-settings/save', dataToSave);
this.showSnackbar('تنظیمات با موفقیت ذخیره شد', 'success');
} catch (error) {
this.showSnackbar('خطا در ذخیره تنظیمات', 'error');
} finally {
this.loading = false;
}
},
async generateCSR() {
this.csrLoading = true;
try {
const response = await axios.post('/api/plugins/tax-settings/generate-csr', this.csrData);
if (response.data.success) {
// this.settings.privateKey = response.data.privateKey;
// نمایش دیالوگ نتیجه
this.resultData.csr = response.data.csr;
this.resultData.privateKey = response.data.privateKey;
this.resultData.publicKey = response.data.publicKey || '';
this.showResultDialog = true;
this.showCSRDialog = false;
this.showSnackbar('کلید و CSR با موفقیت تولید شد', 'success');
} else {
this.showSnackbar(response.data.message || 'خطا در تولید کلید و CSR', 'error');
}
} catch (error) {
this.showSnackbar('خطا در تولید کلید و CSR', 'error');
} finally {
this.csrLoading = false;
}
},
copyToClipboard(text) {
navigator.clipboard.writeText(text);
this.showSnackbar('کپی شد');
},
downloadFile(content, filename) {
const blob = new Blob([content], { type: 'text/plain' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
URL.revokeObjectURL(link.href);
},
showSnackbar(text, color = 'success') {
this.snackbar = {
show: true,
text,
color
};
}
},
mounted() {
this.loadSettings();
}
};
</script>