我想优化现金交易历史记录页面的加载时间并优化bankDetails功能。
每次我加载Cash Ledger或“帐户/银行明细/现金”页面时,要么整个Laravel服务都被压碎,要么此页面的加载时间至少不超过10m,这对于每次Laravel服务都很难处理或重置
是否有优化功能或方法来优化Cash Ledger页面的加载时间?
我的路线是:
Route::get('/bank-details/{id}','BankController@bankDetails')->name('bank.show');
BankController.php bankDetails函数
public function bankDetails($id) {
if(!Auth::user()->isAdmin() && !Auth::user()->isaccountant()) {
return redirectBackWithNotification('error','You are not authorised!');
}
if($id == 'cash') {
$projects = Project::select(['bsoft_projects.project_id','bsoft_projects.project_name'])->get();
return view('admin.accounting.banks.show')
->with([
'projects' => $projects
]);
}
$bank = Bankaccount::findOrFail($id);
if(!$bank->user) {
$payments = Payment::where('payment_from_bank_account','=',$bank->bank_id)
->orWhere('payment_to_bank_account',$bank->bank_id)
->get();
$balance = $bank->bank_balance;
}
else {
$payments = Payment::where('payment_from_bank_account',$bank->bank_id)
->orWhere('payment_to_user',$bank->user->id)
->orWhere('payment_from_user',$bank->user->id)
->get();
$balance = 0;
$exp = 0;
$inc = 0;
foreach ($payments as $payment) {
if($payment->payment_from_user == $bank->user->id) {
$exp += $payment->payment_amount;
}
elseif ($payment->payment_to_user == $bank->user->id) {
$inc += $payment->payment_amount;
}
}
$balance = $inc - $exp;
}
return view('admin.accounting.banks.show')
->with([
'bank' => $bank,'payments' => $payments,'balance' => $balance
]);
}
index.blade.php
<div class="card-footer text-center">
<a href="{{ route('bank.show',['id' => 'cash']) }}" class="btn btn-link text-white">Cash Transaction History</a>
</div>
TransactionsDataTable.vue
<template>
<div class="rbt-data-table">
<div class="card">
<div class="card-header">
<h4 class="text-center w-100">Cash Ledger</h4>
</div>
<div class="card-body">
<div class="selection-form">
<form>
<div class="form-group">
<strong class="font-weight-bold">Select Type: </strong>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline1" class="custom-control-input" v-model="type" value="all">
<label class="custom-control-label" for="customRadioInline1">All</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline2" class="custom-control-input" v-model="type" value="loan">
<label class="custom-control-label" for="customRadioInline2">Loans</label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline3" class="custom-control-input" v-model="type" value="project">
<label class="custom-control-label" for="customRadioInline3">By Project</label>
</div>
</div>
</form>
</div>
<div class="data-table-header" v-if="!isLoading">
<div class="row justify-content-between">
<div class="col-sm-4 d-none d-sm-block">
<div class="data-per-page">
<label>
Show:
<select v-model="perPage" class="custom-select">
<option value="15">15</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</label>
</div>
</div>
<div class="col-sm-8">
<div class="data-search float-right">
<!--<label class="sr-only" for="Search">Search</label>
<div class="input-group">
<input v-model="search" @keyup="fetchData()" type="text" class="form-control" id="Search" placeholder="Search Here">
<div class="input-group-append">
<div class="input-group-text"><i class="feather icon-search text-dark"></i></div>
</div>
</div>-->
<div class="data-search" v-if="type === 'project'">
<label for="project_id">
For Project:
<select class="custom-select" id="project_id" style="width: auto !important;" v-model="projectId">
<option value="">Select A Project</option>
<option v-for="project in projects" :value="project.project_id">{{ project.project_name }}</option>
</select>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-bordered table-striped" id="Franchisetable" style="width: 100%;">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Method</th>
<th scope="col">Type</th>
<th scope="col">Amounts</th>
<th scope="col">Purpose</th>
<th scope="col" v-if="type === 'all'">Project</th>
<th scope="col">From</th>
<th scope="col">To</th>
<th scope="col">Received By</th>
</tr>
</thead>
<tbody>
<tr v-for="data in paginatedData.data">
<th scope="row">{{ data.date }}</th>
<td>{{ data.method }}</td>
<td>{{ data.type }}</td>
<!-- <td class="font-weight-bold">{{ data.amount }}</td>-->
<td style="text-transform: capitalize;">{{ data.purpose }}</td>
<td v-if="type === 'all'">
<a :href="'/project/show/' + data.project_id">{{ data.project_name }}</a>
</td>
<td>{{ data.from }}</td>
<td>{{ data.to }}</td>
<td>{{ data.by }}</td>
</tr>
</tbody>
</table>
</div>
<div class="data-table-footer">
<div class="row">
<div class="col-lg-6">
<div class="data-showing">
Showing <strong>{{ paginatedData.from }} - {{ paginatedData.to }}</strong>
</div>
</div>
<div class="col-lg-6">
<div class="data-pagination">
<ul class="pagination float-right">
<li class="page-item pagination-page-nav" v-if="paginatedData.current_page > 1">
<a href="#" class="page-link" @click.prevent="previousPage">
<i class="fa fa-angle-double-left"></i>
</a>
</li>
<li class="page-item pagination-page-nav" v-if="paginatedData.current_page > 1">
<a href="#" class="page-link" @click.prevent="fetchData(1)">
1
</a>
</li>
<li class="page-item pagination-page-nav active" v-if="paginatedData.current_page">
<a href="#" class="page-link">
{{ paginatedData.current_page }}
</a>
</li>
<li class="page-item pagination-page-nav" v-if="paginatedData.current_page !== paginatedData.last_page">
<a href="#" class="page-link" @click.prevent="nextPage">
<i class="fa fa-angle-double-right"></i>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['projects'],data() {
return {
isLoading: true,paginatedData: {},apiUrl: '/bsoft-api/cash-transactions/',perPage: 5,search: '',type: 'all',projectId: '',deleteFranchiseId: ''
}
},mounted() {
this.fetchData();
},watch: {
perPage(newVal,oldVal) {
if(newVal !== oldVal)
this.fetchData();
},type(newVal,oldVal) {
if(newVal !== oldVal) {
if(newVal === 'project') {
this.paginatedData = {};
}
else {
this.fetchData();
}
}
},projectId(newVal,oldVal) {
if(newVal !== oldVal)
this.fetchData();
}
},methods: {
fetchData(page = 1) {
let self = this;
self.isLoading = true;
let url = self.apiUrl + self.type;
if(self.type === 'project') {
url = url + '/' + self.projectId;
}
axios.get(`${url}?page=${page}&per_page=${self.perPage}&search=${self.search}`)
.then(function (response) {
console.log(response.data);
self.paginatedData = response.data;
self.isLoading = false;
})
.catch(function (error) {
console.log(error.response);
});
},previousPage() {
let page = this.paginatedData.current_page - 1;
this.fetchData(page);
},nextPage() {
let page = this.paginatedData.current_page + 1;
this.fetchData(page);
},openDeleteModal(id) {
this.deleteFranchiseId = id;
$('#franchiseDeleteModal').modal('show');
},deleteFranchise() {
axios.delete('/bs-admin-api/franchise-control/delete/' + this.deleteFranchiseId)
.then((response) => {
this.showToastMsg('Franchise deleted successfully...!','success',3000);
$('#franchiseDeleteModal').modal('hide');
this.fetchData();
})
.catch((error) => {
this.showToastMsg('Something went wrong...! Try again later.','error',5000);
});
},showToastMsg(msg,method = 'show',duration = 2500) {
this.$toasted[method](msg,{
action : {
text : '',icon: 'times',onClick : (e,toastObject) => {
toastObject.goaway(0);
}
},duration: duration
});
},}
}
</script>
Api路线
Route::get('cash-transactions/{type}/{id?}','BankController@cashTransactions');
Api控制器
public function cashTransactions(Request $request,$type,$id = null) {
$per_page = ($request->get('per_page'))? $request->get('per_page') : 5;
$search = htmlspecialchars($request->get('search'));
$roles = Role::whereIn('role_slug',['administrator','accountant'])
->pluck('role_id')
->toArray();
if($type === 'project') {
if(!$id) {
return response()->json('Project Id Required!',404);
}
$payments = Payment::wherePaymentBy('cash')
->where('payment_for_project',$id)
->orderByDesc('payment_date')
->get()
->filter(function ($payment) use ($roles) {
return in_array($payment->activity->activityBy->role_id,$roles);
});
// } else if($type === 'loan') {
// $payments = Payment::wherePaymentBy('cash')
// ->whereIn('payment_purpose',['loan_received','loan_payment'])
// ->orderByDesc('payment_date')
// ->get()
// ->filter(function ($payment) use ($roles) {
// return in_array($payment->activity->activityBy->role_id,$roles);
// });
} else {
$payments = Payment::wherePaymentBy('cash')
->orderByDesc('payment_date')
->get()
->filter(function ($payment) use ($roles) {
return in_array($payment->activity->activityBy->role_id,$roles);
});
}
$page = $request->get('page') ?: (Paginator::resolveCurrentPage() ?: 1);
$paginatedPayments = new LengthAwarePaginator($payments->forPage($page,$per_page),$payments->count(),$per_page,$page);
return response()->json($this->makePaymentCollection($paginatedPayments),200);
}
我想知道我面临的问题在哪里?
是否有解决此优化问题的解决方案,是否有用于优化整个现金交易历史的api函数?
在来自API控制器的cashTransactions中查询以优化此页面的加载时间?
如果我想显示日期或月度现金交易历史记录,我应该怎么做以及可以在哪里添加?最好显示日期或日期,以显示历史记录,还是显示所有贷款,按项目或全部的历史记录>。