progress in costs and redesign logs and api list

This commit is contained in:
Hesabix 2025-03-31 23:55:19 +00:00
parent c26fcf6582
commit e08a6621f1
3 changed files with 469 additions and 465 deletions

View file

@ -1,127 +1,171 @@
<template> <template>
<div class="block block-content-full "> <!-- هدر -->
<div id="fixed-header" class="block-header block-header-default bg-gray-light pt-2 pb-1"> <v-toolbar color="toolbar" flat>
<h3 class="block-title text-primary-dark"> <template v-slot:prepend>
<button @click="$router.back()" type="button" class="float-start d-none d-sm-none d-md-block btn btn-sm btn-link text-warning"> <v-tooltip text="بازگشت" location="bottom">
<i class="fa fw-bold fa-arrow-right"></i> <template v-slot:activator="{ props }">
</button> <v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text" icon="mdi-arrow-right" />
<i class="fa fa-plug-circle-plus"></i> </template>
دسترسی توسعه دهندگان</h3> </v-tooltip>
<div class="block-options"> </template>
<div class="block-options-item"> <v-toolbar-title>
<button @click="submitNew()" class="btn btn-sm btn-success">ایجاد رابط جدید</button> دسترسی توسعه دهندگان
</div> </v-toolbar-title>
</div> <v-spacer></v-spacer>
</div> <v-btn color="success" @click="submitNew" prepend-icon="mdi-plus">
<div class="block-content pt-1 pb-3"> ایجاد رابط جدید
<div class="row"> </v-btn>
<div class="col-sm-12 col-md-12 m-0 p-0"> </v-toolbar>
<div class="mb-1"> <v-text-field
<div class="input-group input-group-sm"> v-model="search"
<span class="input-group-text"><i class="fa fa-search"></i></span> prepend-inner-icon="mdi-magnify"
<input v-model="searchValue" class="form-control" type="text" placeholder="جست و جو ..."> label="جست و جو ..."
</div> variant="outlined"
</div> density="compact"
<EasyDataTable table-class-name="customize-table" hide-details
show-index class="mb-0"
alternating :rounded="0"
></v-text-field>
:search-value="searchValue" <!-- جدول -->
<v-data-table
:headers="headers" :headers="headers"
:items="items" :items="items"
theme-color="#1d90ff" :search="search"
header-text-direction="center"
body-text-direction="center"
rowsPerPageMessage="تعداد سطر"
emptyMessage="اطلاعاتی برای نمایش وجود ندارد"
rowsOfPageSeparatorMessage="از"
:loading="loading" :loading="loading"
hover
:header-props="{ class: 'custom-header' }"
class="elevation-1"
> >
<template #item-operation="{ token }"> <!-- ستون عملیات -->
<span class="text-danger px-1" @click="deleteItem(token)"> <template v-slot:item.operation="{ item }">
<i class="fa fa-trash"></i> <v-btn
</span> icon="mdi-delete"
color="error"
size="small"
variant="text"
@click="deleteItem(item.raw.token)"
>
</v-btn>
</template> </template>
</EasyDataTable>
</div> <!-- لودینگ -->
</div> <template v-slot:loading>
</div> <v-skeleton-loader
</div> type="table-row"
class="my-2"
></v-skeleton-loader>
</template>
<!-- پیام خالی بودن -->
<template v-slot:no-data>
اطلاعاتی برای نمایش وجود ندارد
</template>
<!-- پیام نتیجه جستجو -->
<template v-slot:no-results>
نتیجهای یافت نشد
</template>
</v-data-table>
</template> </template>
<script> <script>
import axios from "axios"; import { ref } from 'vue'
import Swal from "sweetalert2"; import axios from 'axios'
import {ref} from "vue"; import Swal from 'sweetalert2'
export default { export default {
name: "list", name: 'list',
data: ()=>{return { data() {
searchValue: '', return {
loading: ref(true), search: '',
loading: true,
items: [], items: [],
headers: [ headers: [
{ text: "توکن دسترسی", value: "token" , sortable: true}, {
{ text: "مهر زمان انقضا", value: "dateExpire"}, title: 'توکن دسترسی',
{ text: "عملیات", value: "operation"}, align: 'center',
] key: 'token',
}}, sortable: true
methods: {
loadData(){
this.loading = true;
axios.post('/api/business/api/list')
.then((response)=>{
this.items = response.data;
this.loading = false;
})
}, },
submitNew(){ {
this.loading = true; title: 'مهر زمان انقضا',
axios.post('/api/business/api/new') align: 'center',
.then((response)=>{ key: 'dateExpire'
this.items.push(response.data); },
this.loading = false; {
Swal.fire({ title: 'عملیات',
align: 'center',
key: 'operation',
sortable: false
}
]
}
},
methods: {
async loadData() {
this.loading = true
try {
const response = await axios.post('/api/business/api/list')
this.items = response.data
} catch (error) {
console.error('خطا در دریافت اطلاعات:', error)
} finally {
this.loading = false
}
},
async submitNew() {
this.loading = true
try {
const response = await axios.post('/api/business/api/new')
this.items.push(response.data)
await Swal.fire({
text: 'توکن ایجاد شد. رابط توکن: ' + response.data.token, text: 'توکن ایجاد شد. رابط توکن: ' + response.data.token,
confirmButtonText: 'قبول', confirmButtonText: 'قبول',
}) })
}) } catch (error) {
console.error('خطا در ایجاد توکن:', error)
} finally {
this.loading = false
}
}, },
deleteItem(token){
Swal.fire({ async deleteItem(token) {
const result = await Swal.fire({
text: 'آیا برای این مورد مطمئن هستید؟ دسترسی برنامه‌هایی که از این رابط استفاده می‌کنند قطع خواهد شد.', text: 'آیا برای این مورد مطمئن هستید؟ دسترسی برنامه‌هایی که از این رابط استفاده می‌کنند قطع خواهد شد.',
showCancelButton: true, showCancelButton: true,
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: `خیر`, cancelButtonText: 'خیر',
icon: 'warning' icon: 'warning'
}).then((result) => { })
/* Read more about isConfirmed, isDenied below */
if (result.isConfirmed) { if (result.isConfirmed) {
axios.post('/api/business/api/remove/' + token).then((response)=>{ try {
if(response.data.result == 1){ const response = await axios.post('/api/business/api/remove/' + token)
let index = 0; if (response.data.result === 1) {
for(let z=0; z<this.items.length; z++){ this.items = this.items.filter(item => item.token !== token)
index ++; await Swal.fire({
if(this.items[z]['token'] == token){
this.items.splice(index -1 ,1);
}
}
Swal.fire({
text: 'توکن با موفقیت حذف شد.', text: 'توکن با موفقیت حذف شد.',
icon: 'success', icon: 'success',
confirmButtonText: 'قبول' confirmButtonText: 'قبول'
});
}
}) })
} }
}) } catch (error) {
console.error('خطا در حذف توکن:', error)
}
}
} }
}, },
beforeMount() { mounted() {
this.loadData(); this.loadData()
} }
} }
</script> </script>
<style scoped> <style>
.v-data-table th {
white-space: nowrap;
}
</style> </style>

View file

@ -1,298 +1,198 @@
<template> <template>
<div class="block block-content-full "> <v-container fluid class="pa-0">
<div id="fixed-header" class="block-header block-header-default bg-gray-light pt-2 pb-1"> <!-- هدر -->
<h3 class="block-title text-primary-dark"> <v-toolbar color="toolbar" title="هزینه" flat>
<router-link class="text-warning mx-2 px-2" to="/acc/costs/list"> <template v-slot:prepend>
<i class="fa fw-bold fa-arrow-right"></i> <v-tooltip :text="$t('dialog.back')" location="bottom">
</router-link> <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" />
</h3> </template>
<div class="block-options"> </v-tooltip>
<archive-upload v-if="this.$route.params.id != ''" :docid="this.$route.params.id" doctype="cost" </template>
cat="cost"></archive-upload> <v-spacer></v-spacer>
<div class="dropdown me-2">
<button aria-expanded="false" aria-haspopup="true" class="btn btn-sm btn-danger dropdown-toggle" <archive-upload v-if="$route.params.id" :docid="$route.params.id" doctype="cost" cat="cost" />
data-bs-toggle="dropdown" type="button"> افزودن حساب </button>
<div aria-labelledby="dropdown-dropup-secondary" class="border border-danger dropdown-menu" style=""> <v-menu>
<button @click="addItem()" type="button" class="dropdown-item"> <template v-slot:activator="{ props }">
<i class="fa fa-plus"></i> <v-btn color="error" v-bind="props">
مرکز هزینه افزودن حساب
</button> <v-icon end>mdi-chevron-down</v-icon>
<button @click="addBank()" type="button" class="dropdown-item"> </v-btn>
<i class="fa fa-bank"></i> </template>
حساب بانکی <v-list>
</button> <v-list-item @click="addItem()">
<button @click="addCashdesk()" type="button" class="dropdown-item" href="javascript:void(0)"> <template v-slot:prepend>
<i class="fa fa-money-bill-wheat"></i> <v-icon>mdi-plus</v-icon>
صندوق </template>
</button> <v-list-item-title>مرکز هزینه</v-list-item-title>
<button @click="addSalary()" type="button" class="dropdown-item" href="javascript:void(0)"> </v-list-item>
<i class="fa fa-dot-circle"></i> <v-list-item @click="addBank()">
تنخواه گردان <template v-slot:prepend>
</button> <v-icon>mdi-bank</v-icon>
<button @click="addPerson()" type="button" class="dropdown-item" href="javascript:void(0)"> </template>
<i class="fa fa-person"></i> <v-list-item-title>حساب بانکی</v-list-item-title>
شخص </v-list-item>
</button> <v-list-item @click="addCashdesk()">
</div> <template v-slot:prepend>
</div> <v-icon>mdi-cash-register</v-icon>
<button :disabled="this.canSubmit != true" @click="save()" type="button" class="btn btn-sm btn-alt-primary"> </template>
<i class="fa fa-save"></i> <v-list-item-title>صندوق</v-list-item-title>
</v-list-item>
<v-list-item @click="addSalary()">
<template v-slot:prepend>
<v-icon>mdi-wallet</v-icon>
</template>
<v-list-item-title>تنخواه گردان</v-list-item-title>
</v-list-item>
<v-list-item @click="addPerson()">
<template v-slot:prepend>
<v-icon>mdi-account</v-icon>
</template>
<v-list-item-title>شخص</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<v-btn color="primary" :disabled="!canSubmit" @click="save()" class="ms-2">
<v-icon>mdi-content-save</v-icon>
ثبت ثبت
</button> </v-btn>
</div> </v-toolbar>
</div>
<div class="block-content py-3 px-0 vl-parent"> <!-- محتوا -->
<loading color="blue" loader="dots" v-model:active="isLoading" :is-full-page="false" /> <v-container>
<div class="container"> <v-row>
<div class="row mb-2 px-1"> <v-col cols="12" md="6">
<div class="col-sm-12 col-md-6"> <Hdatepicker v-model="data.date" label="تاریخ" />
<date-picker class="" v-model="data.date" format="jYYYY/jMM/jDD" display-format="jYYYY/jMM/jDD" </v-col>
:min="year.start" :max="year.end" /> <v-col cols="12" md="6">
</div> <v-text-field v-model="data.des" label="شرح" variant="outlined"></v-text-field>
<div class="col-sm-12 col-md-6"> </v-col>
<input placeholder="شرح" v-model="data.des" class="form-control form-control-sm" type="text"> </v-row>
</div>
</div> <v-card color="error" variant="outlined" class="mb-4 mt-2">
<div class="row border border-danger rounded-1 mx-1 mb-2"> <v-card-text>
<div class="col-6"> <v-row>
مجموع : <v-col cols="6">
<span class="text-danger">{{ $filters.formatNumber(sum) }}</span> مجموع: {{ $filters.formatNumber(sum) }}
</div> </v-col>
<div class="col-6"> <v-col cols="6">
باقیمانده: باقیمانده: {{ $filters.formatNumber(balance) }}
<span class="text-danger">{{ $filters.formatNumber(balance) }}</span> </v-col>
</div> </v-row>
</div> </v-card-text>
<div class="row"> </v-card>
<div class="col-sm-12 col-md-12" v-for="(item, index) in costs">
<div class="block block-rounded border border-gray"> <!-- مرکز هزینه -->
<div class="block-header bg-default-dark py-1"> <template v-for="(item, index) in costs" :key="'cost'+index">
<h3 class="block-title"> <v-card class="mb-4">
<small class="text-white"> <v-toolbar color="grey-darken-3" density="compact">
<span class="text-danger mx-2">{{ index + 1 }}</span> <v-toolbar-title class="text-white text--secondary">
<i class="fa fa-ticket"></i> <span class="text-error me-2">{{ index + 1 }}</span>
<v-icon color="white">mdi-ticket</v-icon>
مرکز هزینه مرکز هزینه
</small> </v-toolbar-title>
</h3> <v-spacer></v-spacer>
<span class="block-options"> <v-btn icon color="white" @click="removeItem(index)">
<button title="حذف" class="btn-block-option text-white ps-2" @click="removeItem(index)"> <v-icon>mdi-delete</v-icon>
<i class="fa fa-trash"></i> </v-btn>
</button> </v-toolbar>
</span>
</div> <v-card-text>
<div class="block-content-sm mx-2"> <v-row>
<div class="row mb-1"> <v-col cols="12" md="4">
<div class="col-sm-12 col-md-4"> <v-select
<small class="mb-2">مرکز هزینه</small> v-model="item.id"
<treeselect :disable-branch-nodes="true" v-model="item.id" :multiple="false" :items="formattedCostItems"
:options="listscosts" placeholder="انتخاب مرکز هزینه" noOptionsText="آیتمی انتخاب نشده است." item-title="label"
noChildrenText="فاقد زیرمجموعه" noResultsText="نتیجه‌ای یافت نشد" /> item-value="id"
</div> label="مرکز هزینه"
<div class="col-sm-12 col-md-4"> variant="outlined"
<small class="mb-2">مبلغ</small> density="compact"
<money3 @change="calc()" class="form-control form-control-sm" v-model="item.amount" v-bind="currencyConfig"> return-object
</money3> ></v-select>
</div> </v-col>
<div class="col-sm-12 col-md-4"> <v-col cols="12" md="4">
<small>شرح</small> <Hnumberinput
<input v-model="item.des" type="text" class="form-control form-control-sm"> v-model="item.amount"
</div> label="مبلغ"
</div> variant="outlined"
</div> density="compact"
</div> @update:model-value="calc"
</div> />
<div class="col-sm-12 col-md-12 mt-2" v-for="(item, index) in banks"> </v-col>
<div class="block block-rounded border border-gray"> <v-col cols="12" md="4">
<div class="block-header bg-light py-1"> <v-text-field
<h3 class="block-title"> v-model="item.des"
<small class="text-black"> label="شرح"
<span class="mx-2">{{ index + 1 }}</span> variant="outlined"
<i class="fa fa-bank"></i> density="compact"
></v-text-field>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<!-- حساب بانکی -->
<template v-for="(item, index) in banks" :key="'bank'+index">
<v-card class="mb-4">
<v-toolbar color="grey-lighten-3" density="compact">
<v-toolbar-title>
<span class="me-2">{{ index + 1 }}</span>
<v-icon>mdi-bank</v-icon>
حساب بانکی حساب بانکی
</small> </v-toolbar-title>
</h3> <v-spacer></v-spacer>
<span class="block-options"> <v-btn icon color="error" @click="removeBank(index)">
<button title="حذف" class="btn-block-option text-danger ps-2" @click="removeBank(index)"> <v-icon>mdi-delete</v-icon>
<i class="fa fa-trash"></i> </v-btn>
</button> </v-toolbar>
</span>
</div> <v-card-text>
<div class="block-content-sm mx-2"> <v-row>
<div class="row mb-1"> <v-col cols="12" md="4">
<div class="col-sm-12 col-md-4"> <v-autocomplete
<small class="mb-2">بانک</small> v-model="item.id"
<v-cob dir="rtl" :options="listBanks" label="name" v-model="item.id" :items="listBanks"
@option:deselecting="funcCanSubmit()" @search:focus="funcCanSubmit()" item-title="name"
@option:selecting="funcCanSubmit()"> item-value="id"
<template #no-options="{ search, searching, loading }"> label="بانک"
نتیجهای یافت نشد! variant="outlined"
density="compact"
></v-autocomplete>
</v-col>
<v-col cols="12" md="4">
<Hnumberinput
v-model="item.amount"
label="مبلغ"
variant="outlined"
density="compact"
@update:model-value="calc"
/>
</v-col>
<v-col cols="12" md="4">
<v-text-field
v-model="item.des"
label="شرح"
variant="outlined"
density="compact"
></v-text-field>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template> </template>
</v-cob>
</div> <!-- سایر بخشها به همین صورت -->
<div class="col-sm-12 col-md-4"> </v-container>
<small class="mb-2">مبلغ</small>
<money3 @change="calc()" class="form-control form-control-sm" v-model="item.amount" v-bind="currencyConfig"> <!-- لودینگ -->
</money3> <v-overlay v-model="isLoading" class="align-center justify-center">
</div> <v-progress-circular indeterminate size="64"></v-progress-circular>
<div class="col-sm-12 col-md-4"> </v-overlay>
<small>شرح</small> </v-container>
<input v-model="item.des" type="text" class="form-control form-control-sm">
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12 col-md-12 " v-for="(item, index) in salarys">
<div class="block block-rounded border border-gray">
<div class="block-header bg-light py-1">
<h3 class="block-title">
<small class="text-black">
<span class="mx-2">{{ index + 1 }}</span>
<i class="fa fa-dot-circle"></i>
تنخواه گردان
</small>
</h3>
<span class="block-options">
<button title="حذف" class="btn-block-option text-danger ps-2" @click="removeSalary(index)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
<div class="block-content-sm mx-2">
<div class="row mb-1">
<div class="col-sm-12 col-md-4">
<small class="mb-2">تنخواه گردان</small>
<v-cob dir="rtl" :options="listSalarys" label="name" v-model="item.id"
@option:deselecting="funcCanSubmit()" @search:focus="funcCanSubmit()"
@option:selecting="funcCanSubmit()">
<template #no-options="{ search, searching, loading }">
نتیجهای یافت نشد!
</template>
</v-cob>
</div>
<div class="col-sm-12 col-md-4">
<small class="mb-2">مبلغ</small>
<money3 @change="calc()" class="form-control form-control-sm" v-model="item.amount" v-bind="currencyConfig">
</money3>
</div>
<div class="col-sm-12 col-md-4">
<small>شرح</small>
<input v-model="item.des" type="text" class="form-control form-control-sm">
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12 col-md-12 " v-for="(item, index) in cashdesks">
<div class="block block-rounded border border-gray">
<div class="block-header bg-light py-1">
<h3 class="block-title">
<small class="text-black">
<span class="mx-2">{{ index + 1 }}</span>
<i class="fa fa-money-bill-wheat"></i>
صندوق
</small>
</h3>
<span class="block-options">
<button title="حذف" class="btn-block-option text-danger ps-2" @click="removeCashdesk(index)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
<div class="block-content-sm mx-2">
<div class="row mb-1">
<div class="col-sm-12 col-md-4">
<small class="mb-2">صندوق</small>
<v-cob dir="rtl" :options="listCashdesks" label="name" v-model="item.id"
@option:deselecting="funcCanSubmit()" @search:focus="funcCanSubmit()"
@option:selecting="funcCanSubmit()">
<template #no-options="{ search, searching, loading }">
نتیجهای یافت نشد!
</template>
</v-cob>
</div>
<div class="col-sm-12 col-md-4">
<small class="mb-2">مبلغ</small>
<money3 @change="calc()" class="form-control form-control-sm" v-model="item.amount" v-bind="currencyConfig">
</money3>
</div>
<div class="col-sm-12 col-md-4">
<small>شرح</small>
<input v-model="item.des" type="text" class="form-control form-control-sm">
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12 col-md-12 " v-for="(item, index) in persons">
<div class="block block-rounded border border-gray">
<div class="block-header bg-light py-1">
<h3 class="block-title">
<small class="text-black">
<span class="mx-2">{{ index + 1 }}</span>
<i class="fa fa-person"></i>
شخص
</small>
</h3>
<span class="block-options">
<quickAdd :code="0"></quickAdd>
<button title="حذف" class="btn-block-option text-danger ps-2" @click="removePerson(index)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
<div class="block-content-sm mx-2">
<div class="row mb-1">
<div class="col-sm-12 col-md-4">
<small class="mb-2">شخص</small>
<v-cob :filterable="false" @search="searchPerson" class="" dir="rtl" :options="listPersons"
label="nikename" v-model="item.id">
<template v-slot:option="option">
<div class="row mb-1">
<div class="col-12">
<i class="fa fa-user me-2"></i>
{{ option.nikename }}
</div>
<div class="col-12">
<div class="row">
<div v-if="option.mobile != ''" class="col-6">
<i class="fa fa-phone me-2"></i>
{{ option.mobile }}
</div>
<div class="col-6" v-if="parseInt(option.bs) - parseInt(option.bd) != 0">
<i class="fa fa-bars"></i>
تراز:
{{ $filters.formatNumber(Math.abs(parseInt(option.bs) -
parseInt(option.bd))) }}
<span class="" v-if="parseInt(option.bs) - parseInt(option.bd) < 0">
بدهکار </span>
<span class="" v-if="parseInt(option.bs) - parseInt(option.bd) > 0">
بستانکار </span>
</div>
</div>
</div>
</div>
</template>
</v-cob>
</div>
<div class="col-sm-12 col-md-4">
<small class="mb-2">مبلغ</small>
<money3 @change="calc()" class="form-control form-control-sm" v-model="item.amount" v-bind="currencyConfig">
</money3>
</div>
<div class="col-sm-12 col-md-4">
<small>شرح</small>
<input v-model="item.des" type="text" class="form-control form-control-sm">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template> </template>
<script> <script>
@ -300,9 +200,9 @@ import axios from "axios";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import Loading from 'vue-loading-overlay'; import Loading from 'vue-loading-overlay';
import 'vue-loading-overlay/dist/css/index.css'; import 'vue-loading-overlay/dist/css/index.css';
import VuePersianDatetimePicker from 'vue-persian-datetime-picker'
import archiveUpload from "../component/archive/archiveUpload.vue"; import archiveUpload from "../component/archive/archiveUpload.vue";
import Hdatepicker from "@/components/forms/Hdatepicker.vue";
import Hnumberinput from "@/components/forms/Hnumberinput.vue";
import Treeselect from 'vue3-treeselect' import Treeselect from 'vue3-treeselect'
// import the styles // import the styles
import 'vue3-treeselect/dist/vue3-treeselect.css' import 'vue3-treeselect/dist/vue3-treeselect.css'
@ -313,7 +213,9 @@ export default {
Loading, Loading,
Treeselect, Treeselect,
archiveUpload, archiveUpload,
quickAdd quickAdd,
Hdatepicker,
Hnumberinput
}, },
data: () => { data: () => {
return { return {
@ -361,9 +263,14 @@ export default {
beforeRouteUpdate(to, from) { beforeRouteUpdate(to, from) {
this.loadData(to.params.id); this.loadData(to.params.id);
}, },
computed: {
formattedCostItems() {
// تبدیل ساختار درختی به آرایه ساده
return this.flattenCostItems(this.listscosts);
}
},
methods: { methods: {
calc() { calc() {
this.sum = 0; this.sum = 0;
this.costs.forEach((item) => { this.costs.forEach((item) => {
this.sum = parseInt(this.sum) + parseInt(item.amount); this.sum = parseInt(this.sum) + parseInt(item.amount);
@ -384,7 +291,6 @@ export default {
this.balance = parseInt(this.sum) - parseInt(side); this.balance = parseInt(this.sum) - parseInt(side);
this.funcCanSubmit(); this.funcCanSubmit();
}, },
funcCanSubmit() { funcCanSubmit() {
//check form can submit //check form can submit
@ -687,7 +593,20 @@ export default {
} }
}) })
} }
},
flattenCostItems(items) {
let result = [];
items.forEach(item => {
if (!item.children) {
result.push({
id: item.id,
label: item.label
});
} else {
result = result.concat(this.flattenCostItems(item.children));
}
});
return result;
} }
} }
} }

View file

@ -1,76 +1,117 @@
<template> <template>
<div class="block block-content-full "> <!-- هدر -->
<div id="fixed-header" class="block-header block-header-default bg-gray-light pt-2 pb-1"> <v-toolbar color="toolbar" title="تاریخچه رویدادها" flat>
<h3 class="block-title text-primary-dark"> <template v-slot:prepend>
<button @click="$router.back()" type="button" class="float-start d-none d-sm-none d-md-block btn btn-sm btn-link text-warning"> <v-tooltip text="بازگشت" location="bottom">
<i class="fa fw-bold fa-arrow-right"></i> <template v-slot:activator="{ props }">
</button> <v-btn v-bind="props" @click="$router.back()" class="d-none d-sm-flex" variant="text" icon="mdi-arrow-right" />
<i class="fa fa-history"></i> </template>
تاریخچه رویدادها </h3> </v-tooltip>
</template>
</div> </v-toolbar>
<div class="block-content pt-0">
<div class="row"> <v-text-field
<div class="col-sm-12 col-md-12"> v-model="search"
<div class="my-1"> prepend-inner-icon="mdi-magnify"
<div class="input-group input-group-sm"> label="جست و جو ..."
<span class="input-group-text"><i class="fa fa-search"></i></span> variant="outlined"
<input v-model="searchValue" class="form-control" type="text" placeholder="جست و جو ..."> density="compact"
</div> hide-details
</div> class="mb-0"
<EasyDataTable table-class-name="customize-table" :rounded="0"
></v-text-field>
<!-- جدول -->
<v-data-table
:headers="headers" :headers="headers"
:items="items" :items="items"
alternating :search="search"
:search-value="searchValue"
theme-color="#1d90ff"
header-text-direction="center"
body-text-direction="center"
rowsPerPageMessage="تعداد سطر"
emptyMessage="اطلاعاتی برای نمایش وجود ندارد"
rowsOfPageSeparatorMessage="از"
:loading="loading" :loading="loading"
/> hover
</div> :header-props="{ class: 'custom-header' }"
</div> class="elevation-1"
</div> >
</div> <!-- لودینگ -->
<template v-slot:loading>
<v-skeleton-loader
type="table-row"
class="my-2"
></v-skeleton-loader>
</template>
<!-- پیام خالی بودن -->
<template v-slot:no-data>
اطلاعاتی برای نمایش وجود ندارد
</template>
<!-- پیام نتیجه جستجو -->
<template v-slot:no-results>
نتیجهای یافت نشد
</template>
</v-data-table>
</template> </template>
<script> <script>
import { ref } from 'vue'
import axios from "axios"; import axios from 'axios'
import hitable from "../component/hitable.vue";
import {ref} from "vue";
export default { export default {
name: "logs", name: 'logs',
data: ()=>{return { data() {
searchValue: '', return {
loading: ref(true), search: '',
loading: true,
items: [], items: [],
headers: [ headers: [
{ text: "تاریخ", value: "date" }, {
{ text: "کاربر", value: "user"}, title: 'تاریخ',
{ text: "توضیحات", value: "des"}, align: 'center',
{ text: "بخش", value: "part"}, key: 'date',
{ text: "آی پی آدرس", value: "ipaddress"}, },
] {
}}, title: 'کاربر',
methods: { align: 'center',
loadData(){ key: 'user',
axios.post('/api/business/logs/' + localStorage.getItem('activeBid')) },
.then((response)=>{ {
this.items = response.data; title: 'توضیحات',
this.loading=false; align: 'center',
}) key: 'des',
},
{
title: 'بخش',
align: 'center',
key: 'part',
},
{
title: 'آی پی آدرس',
align: 'center',
key: 'ipaddress',
},
],
} }
}, },
beforeMount() { methods: {
this.loadData(); async loadData() {
try {
const response = await axios.post('/api/business/logs/' + localStorage.getItem('activeBid'))
this.items = response.data
} catch (error) {
console.error('خطا در دریافت اطلاعات:', error)
} finally {
this.loading = false
}
}
},
mounted() {
this.loadData()
} }
} }
</script> </script>
<style scoped>
<style>
.v-data-table th {
white-space: nowrap;
}
</style> </style>