You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
516 lines
24 KiB
516 lines
24 KiB
<?php |
|
|
|
namespace App\Http\Controllers\system; |
|
|
|
use App\Exports\ArrayExportH; |
|
use App\Http\Controllers\Controller; |
|
use App\Models\ExportFiles; |
|
use App\Models\StatisticView; |
|
use App\Models\EquipmentView; |
|
use App\Models\MultisysEquipment; |
|
use App\Models\OverSpeedRedEquipment; |
|
use App\Models\User; |
|
use App\Models\ViolationLaw; |
|
use App\Models\ViolationParkingEquipment; |
|
use Carbon\Carbon; |
|
use Illuminate\Http\Request; |
|
use Illuminate\Support\Facades\DB; |
|
use Illuminate\Support\Facades\Log; |
|
use Illuminate\Support\Str; |
|
use Maatwebsite\Excel\Facades\Excel; |
|
|
|
class StatisticsController extends Controller |
|
{ |
|
public function index(Request $request, $type) |
|
{ |
|
$station = []; |
|
$precinct = []; |
|
$location = []; |
|
|
|
$station = EquipmentView::select('station')->distinct()->pluck('station')->toArray(); |
|
$precinct = EquipmentView::select('precinct')->distinct()->pluck('precinct')->toArray(); |
|
$location = EquipmentView::select('location')->distinct()->pluck('location')->toArray(); |
|
|
|
|
|
|
|
$station = array_filter($station, function ($value) { |
|
return $value != null; |
|
}); |
|
|
|
$precinct = array_filter($precinct, function ($value) { |
|
return $value != null; |
|
}); |
|
|
|
$location = array_filter($location, function ($value) { |
|
return $value != null; |
|
}); |
|
// dd($station, $precinct, $location); |
|
if ($type == '1') { |
|
$violationTypes = ViolationLaw::getTypeCodes(); |
|
|
|
return view('system.statistics_1') |
|
->with('violationTypes', $violationTypes) |
|
->with('station', $station) |
|
->with('precinct', $precinct) |
|
->with('location', $location); |
|
} elseif ($type == '2') { |
|
$titles = ['未驗證', '已驗證舉發', '已驗證不舉發', '未處理比例']; |
|
return view('system.statistics_2') |
|
->with('titles', $titles) |
|
->with('station', $station) |
|
->with('precinct', $precinct) |
|
->with('location', $location); |
|
} elseif ($type == '3') { |
|
$titles = ['時間區間1已舉發件數', '時間區間2已舉發件數', '增減']; |
|
return view('system.statistics_3') |
|
->with('titles', $titles) |
|
->with('station', $station) |
|
->with('precinct', $precinct) |
|
->with('location', $location); |
|
} elseif ($type == '4') { |
|
$titles = ['已驗證舉發', '已驗證不舉發', '總件數']; |
|
return view('system.statistics_4') |
|
->with('titles', $titles); |
|
} else { |
|
// 404 |
|
return view('errors.404'); |
|
} |
|
} |
|
|
|
public function getStatistics(Request $request) |
|
{ |
|
$draw = $request->get('draw'); |
|
|
|
// Fetch records |
|
// $violationTypes = ['闖紅燈', '超速', '違停']; |
|
|
|
if ($request->group_at == '分局') { |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, '分局'); |
|
} else if ($request->group_at == '使用單位') { |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, '使用單位'); |
|
} else if ($request->group_at == 'user') { |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, 'user'); |
|
} else { |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, 'location'); |
|
} |
|
|
|
$response = array( |
|
"draw" => intval($draw), |
|
"iTotalRecords" => $totalRecords ?? 0, |
|
"iTotalDisplayRecords" => $totalRecords ?? 0, |
|
"aaData" => $data_arr ?? [] |
|
); |
|
|
|
return $response; |
|
} |
|
|
|
public static function getViolationSummary($request, $group_at) |
|
{ |
|
// dd($request->all()); |
|
if (isset($request->searchByFromdate)) |
|
$searchByFromdate = $request->searchByFromdate; |
|
if (isset($request->searchByTodate)) |
|
$searchByTodate = $request->searchByTodate; |
|
if (isset($request->searchByFromdate2)) |
|
$searchByFromdate2 = $request->searchByFromdate2; |
|
if (isset($request->searchByTodate2)) |
|
$searchByTodate2 = $request->searchByTodate2; |
|
|
|
if (isset($request->export)) |
|
$export = true; |
|
else |
|
$export = false; |
|
|
|
#region DataTable 搜尋屬性 |
|
if (!isset($request->export)) { |
|
$draw = $request->get('draw'); |
|
$start = $request->get("start"); |
|
$rowperpage = $request->get("length"); // Rows display per page |
|
|
|
$columnIndex_arr = $request->get('order'); |
|
$columnName_arr = $request->get('columns'); |
|
$order_arr = $request->get('order'); |
|
$search_arr = $request->get('search'); |
|
|
|
$columnIndex = $columnIndex_arr[0]['column']; // Column index |
|
$columnName = $columnName_arr[$columnIndex]['data']; // Column name |
|
$columnSortOrder = $order_arr[0]['dir']; // asc or desc |
|
$searchValue = $search_arr['value']; // Search value |
|
} else { |
|
$draw = 0; |
|
} |
|
#endregion |
|
|
|
#region Query 舉發類別分析表 |
|
if ($request->reportType == '1') { |
|
if ($group_at == '分局') { |
|
$groups = EquipmentView::getTypePrecinct($request->s1 ?? []); |
|
$groupLocationExpression = ''; |
|
$allSerialNumbers = []; |
|
foreach ($groups as $group => $serialnumbers) { |
|
$allSerialNumbers = array_merge($allSerialNumbers, $serialnumbers); |
|
$serialnumber = implode("','", $serialnumbers); |
|
if ($group == null || $group == '') |
|
continue; |
|
$groupLocationExpression .= " WHEN serialnumber IN ('$serialnumber') THEN '$group'"; |
|
} |
|
$groupLocationExpression = 'CASE' . $groupLocationExpression . ' ELSE NULL END AS group_location'; |
|
|
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} else if ($group_at == '使用單位') { |
|
$groups = EquipmentView::getTypeStation($request->s2 ?? []); |
|
// dd($groups); |
|
$groupLocationExpression = ''; |
|
$allSerialNumbers = []; |
|
foreach ($groups as $group => $serialnumbers) { |
|
$allSerialNumbers = array_merge($allSerialNumbers, $serialnumbers); |
|
$serialnumber = implode("','", $serialnumbers); |
|
if ($group == null || $group == '') |
|
continue; |
|
$groupLocationExpression .= " WHEN serialnumber IN ('$serialnumber') THEN '$group'"; |
|
} |
|
$groupLocationExpression = 'CASE' . $groupLocationExpression . ' ELSE NULL END AS group_location'; |
|
|
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} else { |
|
if (isset($request->s3) && $request->s3 != []) |
|
$allSerialNumbers = EquipmentView::whereIn('location', $request->s3 ?? [])->pluck('serialnumber')->toArray(); |
|
else |
|
$allSerialNumbers = EquipmentView::pluck('serialnumber')->toArray(); |
|
$groupLocationExpression = 'location AS group_location'; |
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} |
|
|
|
if (isset($searchByFromdate) && $searchByFromdate != '') { |
|
$starttime = Carbon::parse($searchByFromdate)->format('Y-m-d'); |
|
$q1 = "AND datatime >= '$starttime 00:00:00'"; |
|
} else { |
|
$q1 = ''; |
|
} |
|
if (isset($searchByTodate) && $searchByTodate != '') { |
|
$endtime = Carbon::parse($searchByTodate)->format('Y-m-d'); |
|
$q2 = "AND datatime <= '$endtime 23:59:59'"; |
|
} else { |
|
$q2 = ''; |
|
} |
|
|
|
$typeCodes = ViolationLaw::getTypeCodes(); |
|
foreach ($typeCodes as $type => $codes) { |
|
// where in violationcode in (codes) and violationtype = type and processcheck = 1 |
|
// 替每個code 加上引號 並用逗號隔開 包含頭尾 |
|
$codes = implode("','", $codes); |
|
$query->selectRaw("SUM(CASE WHEN violationcode IN ('$codes') AND processcheck = 1 $q1 $q2 THEN 1 ELSE 0 END) AS '$type'"); |
|
} |
|
$query->selectRaw("SUM(CASE WHEN processcheck = 1 $q1 $q2 THEN 1 ELSE 0 END) AS total_cases"); |
|
} |
|
// 審核統計分析表 |
|
else if ($request->reportType == '2') { |
|
if ($group_at == '分局') { |
|
$groups = EquipmentView::getTypePrecinct($request->s1 ?? []); |
|
$groupLocationExpression = ''; |
|
$allSerialNumbers = []; |
|
foreach ($groups as $group => $serialnumbers) { |
|
$allSerialNumbers = array_merge($allSerialNumbers, $serialnumbers); |
|
$serialnumber = implode("','", $serialnumbers); |
|
if ($group == null || $group == '') |
|
continue; |
|
$groupLocationExpression .= " WHEN serialnumber IN ('$serialnumber') THEN '$group'"; |
|
} |
|
$groupLocationExpression = 'CASE' . $groupLocationExpression . ' ELSE NULL END AS group_location'; |
|
|
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} else if ($group_at == '使用單位') { |
|
$groups = EquipmentView::getTypeStation($request->s2 ?? []); |
|
$groupLocationExpression = ''; |
|
$allSerialNumbers = []; |
|
foreach ($groups as $group => $serialnumbers) { |
|
$allSerialNumbers = array_merge($allSerialNumbers, $serialnumbers); |
|
$serialnumber = implode("','", $serialnumbers); |
|
if ($group == null || $group == '') |
|
continue; |
|
$groupLocationExpression .= " WHEN serialnumber IN ('$serialnumber') THEN '$group'"; |
|
} |
|
$groupLocationExpression = 'CASE' . $groupLocationExpression . ' ELSE NULL END AS group_location'; |
|
|
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} else { |
|
if (isset($request->s3) && $request->s3 != []) |
|
$allSerialNumbers = EquipmentView::whereIn('location', $request->s3 ?? [])->pluck('serialnumber')->toArray(); |
|
else |
|
$allSerialNumbers = EquipmentView::pluck('serialnumber')->toArray(); |
|
|
|
$groupLocationExpression = 'location AS group_location'; |
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} |
|
|
|
if (isset($searchByFromdate) && $searchByFromdate != '') { |
|
$starttime = Carbon::parse($searchByFromdate)->format('Y-m-d'); |
|
$q1 = "AND datatime >= '$starttime 00:00:00'"; |
|
} else { |
|
$q1 = ''; |
|
} |
|
if (isset($searchByTodate) && $searchByTodate != '') { |
|
$endtime = Carbon::parse($searchByTodate)->format('Y-m-d'); |
|
$q2 = "AND datatime <= '$endtime 23:59:59'"; |
|
} else { |
|
$q2 = ''; |
|
} |
|
|
|
$query->selectRaw("SUM(CASE WHEN processcheck = 0 $q1 $q2 THEN 1 ELSE 0 END) AS '未驗證'"); |
|
$query->selectRaw("SUM(CASE WHEN processcheck = 1 $q1 $q2 THEN 1 ELSE 0 END) AS '已驗證舉發'"); |
|
$query->selectRaw("SUM(CASE WHEN processcheck = 2 $q1 $q2 THEN 1 ELSE 0 END) AS '已驗證不舉發'"); |
|
// 未舉發比例 % = 未舉發 / (已舉發1 + 不舉發2 + 未舉發0) 直接顯示為 (比例數字) + %符號 保留兩位小數 |
|
$query->selectRaw("CONCAT(ROUND(SUM(CASE WHEN processcheck = 0 $q1 $q2 THEN 1 ELSE 0 END) / (SUM(CASE WHEN processcheck = 1 $q1 $q2 THEN 1 ELSE 0 END) + SUM(CASE WHEN processcheck = 2 $q1 $q2 THEN 1 ELSE 0 END) + SUM(CASE WHEN processcheck = 0 $q1 $q2 THEN 1 ELSE 0 END) ) * 100, 2), '%') AS '未處理比例'"); |
|
$query->selectRaw("SUM(CASE WHEN processcheck IN ('0', '1', '2') $q1 $q2 THEN 1 ELSE 0 END) AS total_cases"); |
|
} else if ($request->reportType == '3') { |
|
if ($group_at == '分局') { |
|
$groups = EquipmentView::getTypePrecinct($request->s1 ?? []); |
|
$groupLocationExpression = ''; |
|
$allSerialNumbers = []; |
|
foreach ($groups as $group => $serialnumbers) { |
|
$allSerialNumbers = array_merge($allSerialNumbers, $serialnumbers); |
|
$serialnumber = implode("','", $serialnumbers); |
|
if ($group == null || $group == '') |
|
continue; |
|
$groupLocationExpression .= " WHEN serialnumber IN ('$serialnumber') THEN '$group'"; |
|
} |
|
$groupLocationExpression = 'CASE' . $groupLocationExpression . ' ELSE NULL END AS group_location'; |
|
|
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} else if ($group_at == '使用單位') { |
|
$groups = EquipmentView::getTypeStation($request->s2 ?? []); |
|
$groupLocationExpression = ''; |
|
$allSerialNumbers = []; |
|
foreach ($groups as $group => $serialnumbers) { |
|
$allSerialNumbers = array_merge($allSerialNumbers, $serialnumbers); |
|
$serialnumber = implode("','", $serialnumbers); |
|
if ($group == null || $group == '') |
|
continue; |
|
$groupLocationExpression .= " WHEN serialnumber IN ('$serialnumber') THEN '$group'"; |
|
} |
|
$groupLocationExpression = 'CASE' . $groupLocationExpression . ' ELSE NULL END AS group_location'; |
|
|
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} else { |
|
if (isset($request->s3) && $request->s3 != []) |
|
$allSerialNumbers = EquipmentView::whereIn('location', $request->s3 ?? [])->pluck('serialnumber')->toArray(); |
|
else |
|
$allSerialNumbers = EquipmentView::pluck('serialnumber')->toArray(); |
|
|
|
$groupLocationExpression = 'location AS group_location'; |
|
$query = StatisticView::selectRaw($groupLocationExpression); |
|
$query->whereIn('serialnumber', $allSerialNumbers); |
|
} |
|
|
|
if (isset($searchByFromdate) && $searchByFromdate != '' && isset($searchByTodate) && $searchByTodate != '') { |
|
$starttime = Carbon::parse($searchByFromdate)->format('Y-m-d'); |
|
$endtime = Carbon::parse($searchByTodate)->format('Y-m-d'); |
|
$q1 = "AND datatime >= '$starttime 00:00:00'"; |
|
$q2 = "AND datatime <= '$endtime 23:59:59'"; |
|
} else { |
|
$q1 = ''; |
|
$q2 = ''; |
|
} |
|
if (isset($searchByFromdate2) && $searchByFromdate2 != '' && isset($searchByTodate2) && $searchByTodate2 != '') { |
|
$starttime2 = Carbon::parse($searchByFromdate2)->format('Y-m-d'); |
|
$endtime2 = Carbon::parse($searchByTodate2)->format('Y-m-d'); |
|
$q3 = "AND datatime >= '$starttime2 00:00:00'"; |
|
$q4 = "AND datatime <= '$endtime2 23:59:59'"; |
|
} else { |
|
$q3 = ''; |
|
$q4 = ''; |
|
} |
|
|
|
|
|
|
|
$query->selectRaw("SUM(CASE WHEN processcheck = 1 $q1 $q2 THEN 1 ELSE 0 END) AS '時間區間1已舉發件數'"); |
|
$query->selectRaw("SUM(CASE WHEN processcheck = 1 $q3 $q4 THEN 1 ELSE 0 END) AS '時間區間2已舉發件數'"); |
|
// 時間區間2 - 時間區間1 |
|
$query->selectRaw("SUM(CASE WHEN processcheck = 1 $q3 $q4 THEN 1 ELSE 0 END) - SUM(CASE WHEN processcheck = 1 $q1 $q2 THEN 1 ELSE 0 END) AS '增減'"); |
|
} |
|
// 審核統計分析表 |
|
else if ($request->reportType == '4') { |
|
// distinct user account |
|
$users = User::select('account')->distinct()->pluck('account')->toArray(); |
|
$users = array_filter($users, function ($value) { |
|
return $value != null; |
|
}); |
|
// StatisticView 的jsoncheck是 user account 依據 user account 分組統計 processcheck = 1 的數量 跟 processcheck = 2 的數量 還有總數 |
|
$query = StatisticView::selectRaw("jsoncheck"); |
|
// 增加一條join 用來取得 user account 關聯的 name |
|
$query->leftJoin('users', 'users.account', '=', 'jsoncheck'); |
|
$query->selectRaw("users.name AS 'group_location'"); |
|
|
|
$query->selectRaw("SUM(CASE WHEN processcheck = 1 THEN 1 ELSE 0 END) AS '已驗證舉發'"); |
|
$query->selectRaw("SUM(CASE WHEN processcheck = 2 THEN 1 ELSE 0 END) AS '已驗證不舉發'"); |
|
$query->selectRaw("SUM(CASE WHEN processcheck IN ('1', '2') THEN 1 ELSE 0 END) AS 總件數"); |
|
// jsoncheck AS group_location is not null |
|
$query->whereNotNull('jsoncheck'); |
|
$query->where('jsoncheck', '!=', 'admin'); |
|
$query->groupBy('group_location'); |
|
} |
|
#endregion |
|
|
|
// 所有 processcheck = 1 的案件 |
|
|
|
|
|
$query->groupBy('group_location'); |
|
if (isset($columnName)) |
|
$query->orderBy($columnName, $columnSortOrder); |
|
$data = $query->get(); |
|
$count = count($data); |
|
if (!$export) { |
|
if (isset($start)) |
|
$query->skip($start); |
|
if (isset($rowperpage)) |
|
$query->take($rowperpage); |
|
} |
|
$data = $query->get(); |
|
// 如果data[i] 底下的 group_location 是 null 就不顯示' |
|
$data = $data->filter(function ($value, $key) { |
|
return $value->group_location != null; |
|
}); |
|
|
|
|
|
return [$data, $count]; |
|
} |
|
|
|
public function getStatisticsExport(Request $request) |
|
{ |
|
#region Request 搜尋值 |
|
if (isset($request->searchByFromdate)) |
|
$searchByFromdate = $request->searchByFromdate; |
|
else |
|
$searchByFromdate = ''; |
|
if (isset($request->searchByTodate)) |
|
$searchByTodate = $request->searchByTodate; |
|
else |
|
$searchByTodate = ''; |
|
#endregion |
|
|
|
#region DataTable 搜尋屬性 |
|
if (!isset($request->export)) { |
|
$draw = $request->get('draw'); |
|
$start = $request->get("start"); |
|
$rowperpage = $request->get("length"); // Rows display per page |
|
|
|
$columnIndex_arr = $request->get('order'); |
|
$columnName_arr = $request->get('columns'); |
|
$order_arr = $request->get('order'); |
|
$search_arr = $request->get('search'); |
|
|
|
$columnIndex = $columnIndex_arr[0]['column']; // Column index |
|
$columnName = $columnName_arr[$columnIndex]['data']; // Column name |
|
$columnSortOrder = $order_arr[0]['dir']; // asc or desc |
|
$searchValue = $search_arr['value']; // Search value |
|
} else { |
|
$draw = 0; |
|
} |
|
|
|
|
|
if ($request->group_at == '分局') { |
|
$title = '分局'; |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, '分局'); |
|
} else if ($request->group_at == '使用單位') { |
|
$title = '使用單位'; |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, '使用單位'); |
|
} else if ($request->group_at == 'user') { |
|
$title = '員警姓名'; |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, 'user'); |
|
} else { |
|
$title = '路口'; |
|
[$data_arr, $totalRecords] = self::getViolationSummary($request, 'location'); |
|
} |
|
if ($request->reportType == '1') { |
|
$titlef = '舉發類別分析表'; |
|
} else if ($request->reportType == '2') { |
|
$titlef = '審核統計分析表'; |
|
} else if ($request->reportType == '3') { |
|
$titlef = '審核統計分析表'; |
|
} else if ($request->reportType == '4') { |
|
$titlef = '個別案件審核統計表'; |
|
} |
|
$remark = '報表-' . $titlef . '-' . $title; |
|
$columns = ['group_location', 'total_cases']; |
|
|
|
if ($request->reportType == '1') { |
|
$typeCodes = ViolationLaw::getTypeCodes(); |
|
foreach ($typeCodes as $type => $codes) { |
|
if ($type == 99 || $type == 3 || $type == 1) { |
|
continue; |
|
} |
|
$columns[] = $type; |
|
} |
|
} else if ($request->reportType == '2') { |
|
$columns = ['group_location', 'total_cases', '未驗證', '已驗證舉發', '已驗證不舉發', '未處理比例']; |
|
} else if ($request->reportType == '3') { |
|
$columns = ['group_location', '時間區間1已舉發件數', '時間區間2已舉發件數', '增減']; |
|
} else if ($request->reportType == '4') { |
|
$columns = ['group_location', '已驗證舉發', '已驗證不舉發', '總件數']; |
|
} |
|
|
|
|
|
if (isset($request->searchByFromdate) && isset($request->searchByTodate)) { |
|
$remark = $remark . ' ' . $request->searchByFromdate . ' ~ ' . $request->searchByTodate; |
|
} |
|
$data_arr = $data_arr->toArray(); |
|
$data = array_map(function ($row) use ($columns) { |
|
$data = array_merge(array_flip($columns), array_intersect_key($row, array_flip($columns))); |
|
return $data; |
|
}, $data_arr); |
|
if ($request->reportType == '1' || $request->reportType == '2') { |
|
$column2 = [$title, '總案件數']; |
|
} else { |
|
$column2 = [$title]; |
|
} |
|
|
|
foreach ($columns as $column) { |
|
if ($column == 'group_location' || $column == 'total_cases') { |
|
continue; |
|
} |
|
$column2[] = $column; |
|
} |
|
if (isset($request->searchByFromdate) && isset($request->searchByTodate)) { |
|
$timeRange = $request->searchByFromdate . ' ~ ' . $request->searchByTodate; |
|
} else { |
|
$timeRange = ''; |
|
} |
|
$columnTitle = [ |
|
["【表單名稱】: " . $remark], |
|
["【查詢日期區間】: " . $timeRange], |
|
$column2 |
|
]; |
|
$fileName = 'statistics-' . Str::random(10) . '.xlsx'; |
|
|
|
try { |
|
DB::beginTransaction(); |
|
ExportFiles::create([ |
|
'name' => $fileName, |
|
'path' => 'public/exports', |
|
'type' => 'xlsx', |
|
'status' => '1', |
|
'remark' => "$remark", |
|
'user_id' => auth('api')->user()->id, |
|
]); |
|
$option = [ |
|
'printDef' => $request->printDef ?? 0, |
|
'showPN' => $request->showPN ?? 0, |
|
'showBorder' => $request->showBorder ?? 0, |
|
]; |
|
Excel::store(new ArrayExportH($data, $columnTitle, $option), 'public/exports/' . $fileName, 'local', \Maatwebsite\Excel\Excel::XLSX); |
|
DB::commit(); |
|
} catch (\Throwable $th) { |
|
Log::error("報表匯出失敗: " . $th->getMessage()); |
|
DB::rollBack(); |
|
} |
|
return response()->json(['url' => route('export', ['fileName' => $fileName])], 200); |
|
} |
|
}
|
|
|