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.
1044 lines
45 KiB
1044 lines
45 KiB
<?php |
|
|
|
namespace App\Http\Controllers\System; |
|
|
|
use App\Class\LogWriter; |
|
use App\Exports\ArrayExport; |
|
use App\Http\Controllers\Controller; |
|
use App\Models\ExportFiles; |
|
use App\Models\Interval; |
|
use App\Models\Intervaldis; |
|
use App\Models\IntervalEquipment; |
|
use App\Models\ViolationLaw; |
|
use Carbon\Carbon; |
|
use Illuminate\Http\Request; |
|
use Illuminate\Support\Facades\Auth; |
|
use Illuminate\Support\Facades\DB; |
|
use Illuminate\Support\Facades\Log; |
|
use Maatwebsite\Excel\Facades\Excel; |
|
use Illuminate\Support\Str; |
|
use ZipArchive; |
|
|
|
class IntervalController extends Controller |
|
{ |
|
public $destPath_root; |
|
public $clientDestPath_root; |
|
public $unreportPath_root; |
|
public $month; |
|
|
|
function __construct() |
|
{ |
|
$this->middleware('permission:itl-review|itl-reduction|itl-device-setting|itl-statistics|itl-analysis|itl-read', ['only' => ['Review']]); |
|
$this->middleware('permission:itl-review|permission:itl-reduction', ['only' => ['update']]); |
|
$this->middleware('permission:itl-device-setting', ['only' => ['DeviceSetting']]); |
|
$this->middleware('permission:itl-statistics', ['only' => ['Statistics']]); |
|
$this->middleware('permission:itl-analysis', ['only' => ['Analysis']]); |
|
// OK path |
|
$this->destPath_root = 'D:\\OK\\ITL\\'; |
|
$this->clientDestPath_root = 'D:\\ITL\\'; |
|
// NOK path |
|
$this->unreportPath_root = 'D:\\NOK\\ITL\\'; |
|
$this->month['start'] = Carbon::now()->subDays(8)->format('Y-m-d'); |
|
$this->month['current'] = Carbon::now()->subDays(1)->format('Y-m-d'); |
|
} |
|
|
|
public function Review() |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
$intervaldis = Intervaldis::get(); |
|
$equipmentData = $intervaldis->filter(function ($model) use ($device) { |
|
return in_array($model->start_num, $device) && in_array($model->end_num, $device); |
|
}); |
|
// dd($equipmentData); |
|
return view('system.interval.index') |
|
->with('location', $equipmentData) |
|
->with('month', $this->month); |
|
} |
|
|
|
#region 已審 View |
|
public function Censored(Request $request) |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
$intervaldis = Intervaldis::get(); |
|
$equipmentData = $intervaldis->filter(function ($model) use ($device) { |
|
return in_array($model->start_num, $device) && in_array($model->end_num, $device); |
|
}); |
|
|
|
// dd($data,$page_data); |
|
return view('system.interval.manage') |
|
->with('location', $equipmentData) |
|
->with('month', $this->month); |
|
} |
|
#endregion |
|
|
|
#region 不舉發 View |
|
public function Unreport(Request $request) |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
$intervaldis = Intervaldis::get(); |
|
$equipmentData = $intervaldis->filter(function ($model) use ($device) { |
|
return in_array($model->start_num, $device) && in_array($model->end_num, $device); |
|
}); |
|
|
|
// dd($data,$page_data); |
|
return view('system.interval.unreport') |
|
->with('location', $equipmentData) |
|
->with('month', $this->month); |
|
} |
|
#endregion |
|
|
|
public function update(Request $request, $id) |
|
{ |
|
$data = Interval::find($id); |
|
// 先確認 processcheck 狀態 0 修改 1 舉發 2 不舉發 |
|
// 確認使用者是否可以 review |
|
DB::beginTransaction(); |
|
|
|
try { |
|
// 如果使用者具 審查權限 |
|
if (auth('api')->user()->can('itl-review')) { |
|
// 修改 processcheck = 0 |
|
if ($request->processcheck == 0) { |
|
$data->carnumber = $request->carnumber ?? $data->carnumber; |
|
$data->cartype = $request->cartype ?? $data->cartype; |
|
$data->violationcode = $request->viocode ?? $data->violationcode; |
|
$logData = [ |
|
'action' => 'edit', |
|
'action_detail' => '編輯案件', |
|
'ip' => request()->ip(), |
|
'remark' => "編輯區間案件: $data->carnumber ,案件日期: $data->datatime", |
|
'carnumber' => $data->carnumber, |
|
'location' => $data->location, |
|
]; |
|
} |
|
// 舉發 processcheck = 1 |
|
elseif ($request->processcheck == 1) { |
|
if ($request->carnumber == null || $request->carnumber == '') { |
|
return response()->json(['error' => '請輸入車牌號碼']); |
|
} |
|
if (isset($request->viocode)) { |
|
if ($request->viocode == null || $request->viocode == '') |
|
return response()->json(['error' => '請選擇法條代碼']); |
|
// 如果法條代碼不再資料表中 |
|
if (!ViolationLaw::where('violationcode', $request->viocode)->exists()) { |
|
return response()->json(['error' => '此法條代碼不存在']); |
|
} |
|
} else { |
|
return response()->json(['error' => '請選擇法條代碼']); |
|
} |
|
|
|
$data->carnumber = $request->carnumber ?? $data->carnumber; |
|
$data->cartype = $request->cartype ?? $data->cartype; |
|
$data->violationcode = $request->viocode ?? $data->violationcode; |
|
$data->processcheck = 1; |
|
|
|
$logData = [ |
|
'action' => 'review', |
|
'action_detail' => '舉發案件', |
|
'ip' => request()->ip(), |
|
'remark' => "舉發區間案件: $data->carnumber ,案件日期: $data->end_time", |
|
'carnumber' => $data->carnumber, |
|
'location' => $data->location, |
|
]; |
|
$this->saveIniAndPhoto($data); |
|
} |
|
// 不舉發 processcheck = 2 |
|
elseif ($request->processcheck == 2) { |
|
$data->carnumber = $request->carnumber ?? $data->carnumber; |
|
$data->cartype = $request->cartype ?? $data->cartype; |
|
$data->unreportreason = $request->unreportreason ?? $data->unreportreason; |
|
$data->processcheck = 2; |
|
$logData = [ |
|
'action' => 'review', |
|
'action_detail' => '不舉發案件', |
|
'ip' => request()->ip(), |
|
'remark' => "不舉發區間案件: $data->carnumber ,案件日期: $data->datatime", |
|
'carnumber' => $data->carnumber, |
|
'location' => $data->location, |
|
]; |
|
} |
|
// 還原 processcheck = 3 |
|
elseif ($request->processcheck == 3) { |
|
|
|
// 取得檔案名稱 |
|
$fileName = explode('*', $data->picture); |
|
$fileName = end($fileName); |
|
|
|
// $fileName2 = explode('*', $data->picture2); |
|
// $fileName2 = end($fileName2); |
|
|
|
// 取得時間轉字串 |
|
$time = str_replace('-', '', explode(' ', $data->end_time)[0]); |
|
|
|
// 路徑位置設定 |
|
$destPath_root = $this->destPath_root . Auth::user()->account . "\\" . $time . '\\'; |
|
$clientDestPath_root = $this->clientDestPath_root . Auth::user()->account . "\\" . $time . '\\'; |
|
$unreportPath_root = $this->unreportPath_root . $time . '\\'; |
|
|
|
#region 已審照片 還原時刪除 |
|
$iniPath = $destPath_root . str_replace('jpg', 'ini', $fileName); |
|
$photoPath = $destPath_root . $fileName; |
|
// $photoPath2 = $destPath_root.Auth::user()->account."\\".$time.'\\'.$fileName2; |
|
$clientDestIniPath = $clientDestPath_root . str_replace('jpg', 'ini', $fileName); // 第二路徑測試機用不到 |
|
$clientDestPhotoPath = $clientDestPath_root . $fileName; |
|
// $clientDestPhotoPath2 = $clientDestPath_root.Auth::user()->account."\\".$time.'\\'.$fileName2; |
|
|
|
#region 不舉發合成圖片 還原時刪除 |
|
$unreportiniPath = $unreportPath_root . str_replace('jpg', 'ini', $fileName); |
|
$unreportphotoPath = $unreportPath_root . $fileName; |
|
|
|
if (file_exists($unreportiniPath)) { |
|
unlink($unreportiniPath); |
|
} |
|
if (file_exists($unreportphotoPath)) { |
|
unlink($unreportphotoPath); |
|
} |
|
#endregion |
|
|
|
if (file_exists($iniPath)) { |
|
unlink($iniPath); |
|
} |
|
if (file_exists($photoPath)) { |
|
unlink($photoPath); |
|
} |
|
// if (file_exists($photoPath2)) { unlink($photoPath2);} |
|
if (file_exists($clientDestIniPath)) { |
|
unlink($clientDestIniPath); |
|
} |
|
if (file_exists($clientDestPhotoPath)) { |
|
unlink($clientDestPhotoPath); |
|
} |
|
// if (file_exists($clientDestPhotoPath2)) { unlink($clientDestPhotoPath2);} |
|
|
|
#endregion |
|
|
|
$data->violationcode = null; |
|
$data->unreportreason = ''; |
|
$data->processcheck = 0; |
|
$logData = [ |
|
'action' => 'reduction', |
|
'action_detail' => '還原案件', |
|
'ip' => request()->ip(), |
|
'remark' => "還原區間案件: $data->carnumber ,案件日期: $data->end_time", |
|
'carnumber' => $data->carnumber, |
|
'location' => $data->location, |
|
]; |
|
} |
|
} |
|
|
|
// 紀錄審查者 帳號 |
|
$data->jsoncheck = auth('api')->user()->account; |
|
// 資料儲存 |
|
$data->save(); |
|
// 紀錄 LOG |
|
LogWriter::writeLog($logData, 'api'); |
|
|
|
DB::commit(); |
|
// all good |
|
return response()->json(['success' => $logData['remark']]); |
|
} catch (\Exception $e) { |
|
DB::rollback(); |
|
return response()->json(['error' => '系統錯誤']); |
|
// something went wrong |
|
} |
|
} |
|
|
|
#region DataTable (AJAX刷新用 參數 processcheckStatus 0未審 1已審 2不舉發 "99清冊用")使用 |
|
public function getDataTable(Request $request) |
|
{ |
|
// dd($request->all()); |
|
#region 設備限制 |
|
$device = explode(',', auth("api")->user()->device) ?? [1]; |
|
// dd($device); |
|
#endregion |
|
$processcheckStatus = $request->processcheckStatus; |
|
// dd($processcheckStatus, $device); |
|
[$draw, $totalRecords, $totalRecordswithFilter, $data_arr] = $this->getData($device, $request, $processcheckStatus); |
|
|
|
$response = array( |
|
"draw" => intval($draw), |
|
"iTotalRecords" => $totalRecords, |
|
"iTotalDisplayRecords" => $totalRecordswithFilter, |
|
"aaData" => $data_arr |
|
); |
|
|
|
|
|
// dd($response); |
|
echo json_encode($response); |
|
exit; |
|
} |
|
#endregion |
|
|
|
#region 取得資料 |
|
function getData($device, $request, $processcheckStatus = null) |
|
{ |
|
// 審查狀態 0 未審 1 已審查 2 不舉發 99清冊 |
|
// $processcheckStatus = 2; |
|
// dd($device, $request, $processcheckStatus); |
|
#region Request 搜尋值 |
|
if (isset($request->searchByFromdate)) |
|
$searchByFromdate = $request->searchByFromdate; |
|
if (isset($request->searchByTodate)) |
|
$searchByTodate = $request->searchByTodate; |
|
|
|
//地點搜尋 |
|
if (isset($request->serialnumber)) { |
|
$itl_dis = explode('-', $request->serialnumber); |
|
$dis = Intervaldis::where('start_serialnumber', $itl_dis[0])->where('end_serialnumber', $itl_dis[1])->first() ?? null; |
|
if (isset($dis)) { |
|
$serialNumber = []; |
|
$serialNumber['start'] = $dis->start_num; |
|
$serialNumber['end'] = $dis->end_num; |
|
} |
|
} |
|
|
|
//車牌搜尋 |
|
if (isset($request->carnumber)) |
|
$carnumber = $request->carnumber; |
|
|
|
//不舉發理由搜尋 |
|
if (isset($request->unreportreason)) |
|
$unreportreason = $request->unreportreason; |
|
#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; |
|
} |
|
#endregion |
|
|
|
// Fetch records |
|
$records = Interval::query(); |
|
$records->where('mergedone', 1); |
|
|
|
if (isset($columnName)) |
|
$records->orderBy($columnName, $columnSortOrder); |
|
if (isset($searchValue)) |
|
$records->where('carnumber', 'like', '%' . $searchValue . '%'); |
|
//已審未審 |
|
//清冊用 99 |
|
#region 審查狀態 |
|
if ($processcheckStatus == 99) { |
|
$processcheckStatus = $request->processCheck; |
|
if ($processcheckStatus == 99 || $processcheckStatus == null) |
|
$records->whereIn('processcheck', [0, 1, 2]); |
|
else { |
|
$records->where('processcheck', $processcheckStatus); |
|
} |
|
} else { |
|
$records->where('processcheck', $processcheckStatus); |
|
} |
|
#endregion |
|
|
|
#region 常用搜尋條件 |
|
//設備限制 |
|
$records->whereIn('start_serialnumber', $device); |
|
$records->whereIn('end_serialnumber', $device); |
|
$totalRecords = $records->count(); |
|
//時間限制 |
|
if (isset($searchByFromdate)) |
|
$records->where('end_time', ">", $searchByFromdate . ' 00:00:00'); |
|
if (isset($searchByTodate)) |
|
$records->where('end_time', "<", $searchByTodate . ' 23:59:59'); |
|
|
|
// //地點篩選 |
|
if (isset($serialNumber)) |
|
$records->where('start_serialnumber', $serialNumber['start'])->where('end_serialnumber', $serialNumber['end']); |
|
// //車牌篩選 |
|
if (isset($carnumber)) |
|
$records->where('carnumber', 'like', '%' . $carnumber . '%'); |
|
// //不舉發理由 |
|
// if (isset($unreportreason)) |
|
// $records->where('unreportreason', 'like', '%' . $unreportreason . '%'); |
|
|
|
#endregion |
|
|
|
|
|
$totalRecordswithFilter = $records->count(); |
|
|
|
#region 報表類型 |
|
//如果有報表類型(1,2,3,...),並需要特別處理欄位的報表 |
|
if (isset($request->statisticstype)) { |
|
if ($request->statisticstype == 2) |
|
$records->groupBy('serialnumber', 'cartype')->select('*', DB::raw('count(*) as count')); |
|
else if ($request->statisticstype == 3) { |
|
$currentYear = date('Y'); |
|
$lastYear = $currentYear - 1; |
|
$groupbyPara1 = "CAST(DATE_FORMAT(datatime, '%H') AS INT)"; |
|
$records->groupBy(DB::raw($groupbyPara1), 'serialnumber', 'violationtype')->select('*', DB::raw('COUNT(*) as count, CONCAT(CAST(DATE_FORMAT(datatime,"%H") as INT),"-",CAST(DATE_FORMAT(DATE_ADD(datatime,INTERVAL +1 HOUR),"%H") as INT)) AS period')); |
|
// $records->addSelect(DB::raw("(SELECT COUNT(*) FROM interval AS sub_records WHERE DATE_FORMAT(sub_records.datatime,'%Y') = '$lastYear' AND sub_records.serialnumber = interval.serialnumber AND sub_records.violationtype = interval.violationtype) AS last_count")); |
|
$records->orderBy(DB::raw($groupbyPara1), 'ASC'); |
|
} else if ($request->statisticstype == 4) { |
|
if ($request->searchByYear) |
|
$records->whereYear('datatime', $request->searchByYear); |
|
$records->groupBy('serialnumber', 'cartype')->select('*', DB::raw('count(*) as count')); |
|
// 去年同期資料 與上述條件相同 |
|
$lastYear = $request->searchByYear - 1; |
|
// $records->addSelect(DB::raw("(SELECT COUNT(*) FROM interval AS sub_records WHERE DATE_FORMAT(sub_records.datatime,'%Y') = '$lastYear' AND sub_records.serialnumber = interval.serialnumber AND sub_records.cartype = interval.cartype) AS last_count")); |
|
// dd($records->toSql(), $records->getBindings()); |
|
} else if ($request->statisticstype == 5) { |
|
} |
|
} else { |
|
$records->select('*'); |
|
} |
|
#endregion |
|
|
|
#region DataTable 分頁(報表不分頁) |
|
if (!isset($request->export)) { |
|
if (isset($start)) |
|
$records->skip($start); |
|
if (isset($rowperpage)) |
|
$records->take($rowperpage); |
|
} |
|
#endregion |
|
// dd($records->toSql(), $records->getBindings()); |
|
$records = $records->get(); |
|
|
|
#region 資料處理 |
|
$data_arr = array(); |
|
// $sno = $start + 1; |
|
foreach ($records as $record) { |
|
//還原用id |
|
$id = $record->id; |
|
$violationcode = $record->violationcode; |
|
$processcheck = $record->processcheck; |
|
$postcheck = $record->postcheck ?? 0; |
|
|
|
//報表用的欄位,避免前端錯誤,給預設值 |
|
$count = $record->count ?? 0; |
|
$period = $record->period ?? ""; |
|
|
|
$cartypeTitle = [ |
|
'1' => "汽車", |
|
'2' => "機車", |
|
'3' => "重型機車", |
|
'4' => "輕型機車", |
|
'8' => "微型電動二輪車", |
|
'99' => "大型重型機車", |
|
'98' => "大型車" |
|
]; |
|
$cartypeCode = [ |
|
'汽車' => "1", |
|
'機車' => "2", |
|
'重型機車' => "3", |
|
'輕型機車' => "4", |
|
'微型電動二輪車' => "8", |
|
'大型重型機車' => "99", |
|
'大型車' => "98" |
|
]; |
|
|
|
$processCheckTitle = [ |
|
'0' => "未審", |
|
'1' => "已審查", |
|
'2' => "不舉發" |
|
]; |
|
|
|
if (!isset($cartype)) |
|
$cartype = 1; |
|
|
|
if ($violationcode != null) { |
|
$violationdata = "[$violationcode]" . ViolationLaw::where('violationcode', $violationcode)->first()->display_name; |
|
} |
|
else{ |
|
if ($record->speed - $record->limit_speed < 20){ |
|
$violationcode = '4000011'; |
|
} else if ($record->speed - $record->limit_speed <= 40) { |
|
$violationcode = '4000012'; |
|
} else if ($record->speed - $record->limit_speed <= 60) { |
|
$violationcode = '4310255'; |
|
} else if ($record->speed - $record->limit_speed <= 80) { |
|
$violationcode = '4310256'; |
|
} else if ($record->speed - $record->limit_speed > 80) { |
|
$violationcode = '4310257'; |
|
} |
|
else{ |
|
|
|
} |
|
} |
|
if ($record->carkind == 'null'){ |
|
$carkind = '汽車'; |
|
} |
|
else{ |
|
$carkind = $record->carkind; |
|
} |
|
$data_arr[] = array( |
|
"id" => $id, |
|
"intervalnumber" => $record->intervalnumber, |
|
"start_time" => $record->start_time, |
|
"end_time" => $record->end_time, |
|
"start_location" => $record->start_location, |
|
"end_location" => $record->end_location, |
|
"start_serialnumber" => $record->start_serialnumber, |
|
"end_serialnumber" => $record->end_serialnumber, |
|
"carnumber" => $record->carnumber, |
|
"speed" => $record->speed, |
|
"limit_speed" => $record->limit_speed, |
|
"diff" => $record->diff, |
|
"distance" => $record->distance, |
|
"merge_picture" => "ParsingFiles/Interval/". str_replace('*', '/', $record->merge_picture) , |
|
// "merge_picture" => '123.jpg', |
|
"serialnumber" => $record->serialnumber, |
|
//影片連結 (用照片的路徑取代成mp4 picture= _A picture2= _B) |
|
"start_video" => str_replace('.jpg', '.mp4', $record->start_video), |
|
"end_video" => str_replace('.jpg', '.mp4', $record->end_video), |
|
"violationdata" => $violationdata ?? '', |
|
"violationcode" => $violationcode ?? null, |
|
"cartype" => $cartypeCode[$carkind], |
|
"carkind" => $carkind, |
|
// "carkind" => $cartypeTitle[$record->cartype], |
|
"lawType" => $record->lawType ?? '', |
|
"unreportreason" => $record->unreportreason ?? '', |
|
"postcheck" => $postcheck, |
|
// 清冊用 |
|
"processcheck" => $processCheckTitle[$processcheck], |
|
"faildata" => $record->faildata, |
|
// "searchByFromdate" => $searchByFromdate, |
|
// "searchByTodate"=> $searchByTodate, |
|
"count" => $count, |
|
"period" => $period, |
|
"last_count" => $record->last_count ?? 0 |
|
); |
|
} |
|
#endregion |
|
|
|
#region 如果需要去年同期比較 |
|
$data_last_year = []; |
|
if (isset($request->searchByFromdate) && isset($request->searchByTodate) && $processcheckStatus == 99) { |
|
$searchByFromdate = $request->searchByFromdate; |
|
$searchByTodate = $request->searchByTodate; |
|
$searchByFromdate = Carbon::parse($searchByFromdate)->subYear()->format('Y-m-d'); |
|
$searchByTodate = Carbon::parse($searchByTodate)->subYear()->format('Y-m-d'); |
|
$records = Interval::query(); |
|
$records->where('datatime', ">", $searchByFromdate . ' 00:00:00'); |
|
$records->where('datatime', "<", $searchByTodate . ' 23:59:59'); |
|
$records->whereIn('processcheck', [0, 1, 2]); |
|
$records->whereIn('serialnumber', $device); |
|
if ($request->statisticstype == 2) |
|
$records->groupBy('serialnumber', 'cartype')->select('*', DB::raw('count(*) as count')); |
|
if ($request->statisticstype == 3) { |
|
$groupbyPara1 = "CAST(DATE_FORMAT(datatime, '%H') AS INT)"; |
|
$currentYear = date('Y'); |
|
$lastYear = $currentYear - 1; |
|
$records->groupBy(DB::raw($groupbyPara1), 'serialnumber', 'violationtype')->select('*', DB::raw('COUNT(*) as count, CONCAT(CAST(DATE_FORMAT(datatime,"%H") as INT),"-",CAST(DATE_FORMAT(DATE_ADD(datatime,INTERVAL +1 HOUR),"%H") as INT)) AS period')); |
|
$records->addSelect(DB::raw("(SELECT COUNT(*) FROM interval AS sub_records WHERE DATE_FORMAT(sub_records.datatime,'%Y') = '$lastYear' AND sub_records.serialnumber = interval.serialnumber AND sub_records.violationtype = interval.violationtype) AS last_count")); |
|
$records->orderBy(DB::raw($groupbyPara1), 'ASC'); |
|
} |
|
$records = $records->get(); |
|
foreach ($records as $record) { |
|
$data_last_year[] = array( |
|
"datatime" => $record->datatime, |
|
"serialnumber" => $record->serialnumber, |
|
"location" => $record->location, |
|
"carnumber" => $record->carnumber, |
|
"picture" => $record->picture, |
|
"picture2" => $record->picture2, |
|
"cartype" => $record->cartype, |
|
"unreportreason" => $record->unreportreason ?? '', |
|
"unreportpicture" => $record->unreportpicture ?? $record->picture, |
|
"processcheck" => $processCheckTitle[$record->processcheck], |
|
"count" => $record->count ?? 0, |
|
"period" => $record->period ?? "", |
|
"last_count" => $record->last_count ?? 0 |
|
); |
|
} |
|
} |
|
|
|
return [$draw, $totalRecords, $totalRecordswithFilter, $data_arr, $data_last_year]; |
|
} |
|
#endregion |
|
|
|
|
|
|
|
// 清冊用 |
|
public function Statistics() |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
// 違規地點 group by |
|
$equipmentData = new IntervalEquipment(); |
|
$serialNumber = $equipmentData::whereIn('serialnumber', $device)->groupBy('serialnumber')->get(['serialnumber', 'location']); |
|
// 違規類型 group by |
|
$violationparking = new Interval(); |
|
$violationtype = $violationparking::whereIn('serialnumber', $device)->groupBy('violationtype')->pluck('violationtype'); |
|
|
|
return view('system.interval.statistics') |
|
->with('serialNumber', $serialNumber) |
|
->with('violationtype', $violationtype); |
|
} |
|
public function StatisticsYears() |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
// 違規地點 group by |
|
$equipmentData = new IntervalEquipment(); |
|
$serialNumber = $equipmentData::whereIn('serialnumber', $device)->groupBy('serialnumber')->get(['serialnumber', 'location']); |
|
// 違規類型 group by |
|
$violationparking = new Interval(); |
|
$violationtype = $violationparking::whereIn('serialnumber', $device)->groupBy('violationtype')->pluck('violationtype'); |
|
|
|
return view('system.interval.statistics_years') |
|
->with('serialNumber', $serialNumber) |
|
->with('violationtype', $violationtype); |
|
} |
|
public function getStatisticsData(Request $request) |
|
{ |
|
#region 設備限制 |
|
$device = explode(',', auth("api")->user()->device) ?? [1]; |
|
#endregion |
|
$processcheckStatus = 99; |
|
|
|
[$draw, $totalRecords, $totalRecordswithFilter, $data_arr, $data_arr2] = $this->getData($device, $request, $processcheckStatus); |
|
|
|
$response = array( |
|
"draw" => intval($draw), |
|
"iTotalRecords" => $totalRecords, |
|
"iTotalDisplayRecords" => $totalRecordswithFilter, |
|
"aaData" => $data_arr |
|
); |
|
|
|
return $response; |
|
} |
|
|
|
public function getStatisticsDataExport(Request $request) |
|
{ |
|
#region 設備限制 |
|
$device = explode(',', auth("api")->user()->device) ?? [1]; |
|
#endregion |
|
$processcheckStatus = 99; |
|
|
|
if ($request->statisticstype == 1) { |
|
$remark = '違規件數清冊'; |
|
$columns = ['datatime', 'serialnumber', 'location', 'carnumber', 'violationtype', 'processcheck']; |
|
$columnTitle = [ |
|
["【表單名稱】:", $remark], |
|
["【違規日期區間】:", $request->searchByFromdate, " ~ ", $request->searchByTodate], |
|
['違規時段', '設備編號', '違規地點', '車號', '違規類型', '審查狀態'] |
|
]; |
|
} elseif ($request->statisticstype == 2) { |
|
$remark = '違規件數統計清冊'; |
|
$columns = ['serialnumber', 'location', 'violationtype', 'carkind', 'count']; |
|
$columnTitle = [ |
|
["【表單名稱】:", $remark], |
|
["【違規日期區間】:", $request->searchByFromdate, " ~ ", $request->searchByTodate], |
|
['設備編號', '違規地點', '違規類型', '車種', '統計'] |
|
]; |
|
} elseif ($request->statisticstype == 3) { |
|
$remark = '違規時段件數統計清冊'; |
|
$columns = ['serialnumber', 'location', 'period', 'violationtype', 'count']; |
|
$columnTitle = [ |
|
["【表單名稱】:", $remark], |
|
["【違規日期區間】:", $request->searchByFromdate, " ~ ", $request->searchByTodate], |
|
['設備編號', '違規地點', '違規時段', '違規類型', '統計'] |
|
]; |
|
} elseif ($request->statisticstype == 3) { |
|
$remark = '違規時段件數統計清冊'; |
|
$columns = ['serialnumber', 'location', 'period', 'violationtype', 'count']; |
|
$columnTitle = [ |
|
["【表單名稱】:", $remark], |
|
["【違規日期區間】:", $request->searchByFromdate, " ~ ", $request->searchByTodate], |
|
['設備編號', '違規地點', '違規時段', '違規類型', '統計'] |
|
]; |
|
} |
|
|
|
if (isset($request->searchByFromdate) && isset($request->searchByTodate)) { |
|
} |
|
|
|
[$draw, $totalRecords, $totalRecordswithFilter, $data_arr, $data_arr2] = $this->getData($device, $request, $processcheckStatus); |
|
$data = array_map(function ($row) use ($columns) { |
|
$data = array_merge(array_flip($columns), array_intersect_key($row, array_flip($columns))); |
|
return $data; |
|
}, $data_arr); |
|
|
|
$fileName = 'itl-' . Str::random(10) . '.xlsx'; |
|
ExportFiles::create([ |
|
'name' => $fileName, |
|
'path' => 'public/exports', |
|
'type' => 'xlsx', |
|
'status' => '1', |
|
'remark' => "區間-$remark", |
|
'user_id' => auth('api')->user()->id, |
|
]); |
|
Excel::store(new ArrayExport($data, $columnTitle), 'public/exports/' . $fileName, 'local', \Maatwebsite\Excel\Excel::XLSX); |
|
|
|
return response()->json(['url' => route('export', ['fileName' => $fileName])], 200); |
|
} |
|
|
|
public function Export(Request $request, $fileName) |
|
{ |
|
$file = ExportFiles::where('name', $fileName)->first(); |
|
$filePath = storage_path('app/public/exports/' . $fileName); |
|
if (file_exists($filePath)) { |
|
return response()->download($filePath, $file->remark . '.' . $file->type); |
|
} else { |
|
return response()->json(['error' => '檔案不存在']); |
|
} |
|
} |
|
|
|
// 數據分析 vpkAnalysis |
|
public function Analysis() |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
// 違規地點 group by |
|
$equipmentData = new IntervalEquipment(); |
|
$serialNumber = $equipmentData::whereIn('serialnumber', $device)->groupBy('serialnumber')->get(['serialnumber', 'location']); |
|
// 違規類型 group by |
|
$violationparking = new Interval(); |
|
$violationtype = $violationparking::whereIn('serialnumber', $device)->groupBy('violationtype')->pluck('violationtype'); |
|
|
|
return view('system.interval.analysis') |
|
->with('serialNumber', $serialNumber) |
|
->with('violationtype', $violationtype); |
|
} |
|
|
|
public function getAnalysisData(Request $request) |
|
{ |
|
$device = explode(',', auth("api")->user()->device) ?? [1]; |
|
$records = Interval::query(); |
|
$records->whereIn('serialnumber', $device)->whereIn('processcheck', [1, 3]); |
|
// dd($request->all()); |
|
if (isset($request->search_fromdate)) |
|
$records->where('datatime', ">", $request->search_fromdate . ' 00:00:00'); |
|
if (isset($request->search_todate)) |
|
$records->where('datatime', "<", $request->search_todate . ' 23:59:59'); |
|
//地點搜尋 |
|
if (isset($request->location)) |
|
$records->where('serialnumber', $request->location); |
|
if (isset($request->violation_type)) |
|
$records->where('violationtype', $request->violation_type); |
|
|
|
$data = $records->get(); |
|
if (isset($request->chart_type)) { |
|
if ($request->chart_type == '1') { |
|
// 根據違規類型分類 並計算每一類的總數 |
|
$data = $data->groupBy('violationtype')->map(function ($item, $key) { |
|
return [ |
|
'title' => $key, |
|
'times' => $item->count() |
|
]; |
|
})->toArray(); |
|
$data = array_values($data); |
|
} elseif ($request->chart_type == '2') { |
|
// 根據違規類型分類 並計算每一類的總數 |
|
$data = $data->groupBy('location')->map(function ($item, $key) { |
|
return [ |
|
'title' => $key, |
|
'times' => $item->count() |
|
]; |
|
})->toArray(); |
|
$data = array_values($data); |
|
} elseif ($request->chart_type == '3') { |
|
$records2 = Interval::query(); |
|
$records2->whereIn('serialnumber', $device)->whereIn('processcheck', [1, 3]); |
|
// dd($request->all()); |
|
if (isset($request->search_fromdate)) |
|
$records2->where('datatime', ">", $request->search_fromdate . ' 00:00:00'); |
|
if (isset($request->search_todate)) |
|
$records2->where('datatime', "<", $request->search_todate . ' 23:59:59'); |
|
//地點搜尋 |
|
if (isset($request->location)) |
|
$records2->where('serialnumber', $request->location); |
|
if (isset($request->violation_type)) |
|
$records2->where('violationtype', $request->violation_type); |
|
$violationTypes = $records2->groupBy('violationtype')->select('violationtype')->get()->toArray(); |
|
$violationTypes = array_column($violationTypes, 'violationtype'); |
|
// violationTypes key value 互換 |
|
$violationTypesKey = array_flip($violationTypes); |
|
// dd($violationTypes); |
|
// 初始化結果陣列 |
|
$response = []; |
|
for ($hour = 0; $hour <= 23; $hour++) { |
|
// 補零 01, 02, 03, ..., 09 |
|
// $hour = str_pad($hour, 2, '0', STR_PAD_LEFT); |
|
// 初始化結果陣列 |
|
$response[$hour] = [ |
|
'category' => $hour, |
|
]; |
|
for ($i = 0; $i < count($violationTypes); $i++) { |
|
$response[$hour][$i] = 0; |
|
} |
|
} |
|
$data = $records->get(); |
|
$data = $data->groupBy(function ($item, $key) { |
|
return intval(Carbon::parse($item->datatime)->format('H')); |
|
})->map(function ($item, $key) use (&$response, $violationTypesKey) { |
|
$item->groupBy('violationtype')->map(function ($item, $viotype) use ($key, &$response, $violationTypesKey) { |
|
$response[$key][$violationTypesKey[$viotype]] = $item->count(); |
|
}); |
|
}); |
|
|
|
$data = $response; |
|
// dd($data); |
|
} |
|
} |
|
|
|
// dd($data); |
|
return response()->json(['data' => $data, 'chart_type' => $request->chart_type, 'violationtype' => $violationTypes ?? ''], 200); |
|
} |
|
|
|
// statistics |
|
// public function statistics() |
|
// { |
|
// return view('system.interval.statistics'); |
|
// } |
|
|
|
public function getStatisticsTest(Request $request) |
|
{ |
|
$request->statisticstype; |
|
// 讀取json file (storage/app/data/get-itl-statistics-1~3.json ) |
|
|
|
$json = file_get_contents(storage_path('app/data/get-itl-statistics-1.json')); |
|
} |
|
|
|
//getLocationByViolationtype |
|
public function getLocationByViolationtype(Request $request) |
|
{ |
|
$device = explode(',', auth()->user()->device) ?? [1]; |
|
$records = Interval::query(); |
|
$records->whereIn('serialnumber', $device); |
|
if (isset($request->violationtype)) |
|
$records->whereIn('violationtype', $request->violationtype); |
|
$records->groupBy('serialnumber')->get(['serialnumber', 'location']); |
|
$data = $records->get(); |
|
return response()->json(['data' => $data]); |
|
} |
|
#region 產生Ini |
|
function saveIniAndPhoto($data) |
|
{ |
|
// $fileName = explode('*', $data->endpicture); |
|
// $fileName = end($fileName); |
|
|
|
$time = explode(' ', $data->end_time); |
|
$date = str_replace('-', '', $time[0]); |
|
$time = str_replace(':', '', $time[1]); |
|
$time = explode('.', $time); |
|
$time = $time[0]; |
|
|
|
$savePath = $this->destPath_root . $date; |
|
$saveclientPath = $this->clientDestPath_root . $date; |
|
|
|
$iniFileName = $date . '_' . $time . '_' . substr($data->intervalnumber, -4) . '_A.txt'; |
|
|
|
// $mergePhotoPath = str_replace('-merge.jpg', '~', explode('*', $data->startpicture)[4]) . str_replace('-merge.jpg', '-interval.png', explode('*', $data->endpicture)[4]); |
|
// $mergePhotoPath = storage_path('app' . '\\' . 'ParsingFiles' . '\\' . 'interval' . '\\' . explode('*', $data->startpicture)[0] . '\\' . explode('*', $data->startpicture)[1] . '\\' . explode('*', $data->startpicture)[2] . '\\' . 'Interval' . '\\' . $mergePhotoPath); |
|
$mergePhotoPath = $data->merge_picture; |
|
$mergePhotoPath = str_replace('*', '/', $mergePhotoPath); |
|
$mergePhotoPath = storage_path('app/ParsingFiles/Interval/' . $mergePhotoPath); |
|
// dd($mergePhotoPath); |
|
|
|
$carkindcode = ''; |
|
switch ($data->carkind) { |
|
case "汽車": |
|
$carkindcode = '1'; |
|
break; |
|
case "拖車": |
|
$carkindcode = '2'; |
|
break; |
|
case "重型機車": |
|
$carkindcode = '3'; |
|
break; |
|
case "輕型機車": |
|
$carkindcode = '4'; |
|
break; |
|
case "動力機械": |
|
$carkindcode = '5'; |
|
break; |
|
case "臨時車牌": |
|
$carkindcode = '6'; |
|
break; |
|
} |
|
|
|
$speed_diff = $data->passspeed - $data->limitspeed; |
|
|
|
$viocode = ''; |
|
if ($speed_diff <= 20) { |
|
$viocode = '4000011'; |
|
} elseif ($speed_diff > 20 && $speed_diff <= 40) { |
|
$viocode = '4000012'; |
|
} elseif ($speed_diff > 40 && $speed_diff <= 60) { |
|
$viocode = '4000013'; |
|
} elseif ($speed_diff > 60 && $speed_diff <= 80) { |
|
$viocode = '4310225'; |
|
} elseif ($speed_diff > 80 && $speed_diff <= 100) { |
|
$viocode = '4310226'; |
|
} elseif ($speed_diff > 100) { |
|
$viocode = '4310227'; |
|
} else { |
|
$viocode = 'error'; |
|
} |
|
|
|
if (isset($data->viocode)) { |
|
$viocode = $data->viocode; |
|
} |
|
|
|
$iniData = |
|
'車號=' . $data->carnumber . "\r\n" . |
|
'車別代碼=' . $carkindcode . "\r\n" . |
|
'違規日期_迄=' . substr(str_replace('-', '/', $data->end_time), 0, 10) . "\r\n" . |
|
'違規時間_迄=' . substr(str_replace('-', '/', $data->end_time), 11, 8) . "\r\n" . |
|
'違規地點=' . $data->location . "\r\n" . |
|
'違規條款代碼=' . $viocode . "\r\n" . |
|
'限速=' . $data->limit_speed . "\r\n" . |
|
'車速=' . $data->speed . "\r\n" . |
|
'距離=' . $data->distance . "\r\n" . |
|
'舉發單位代碼=' . "\r\n" . |
|
'舉發員警代碼=' . "\r\n" . |
|
'違規相片名稱1=' . str_replace('txt', 'jpg', $iniFileName) . "\r\n" . |
|
'違規相片名稱2=' . "\r\n" . |
|
'違規相片名稱3=' . "\r\n" . |
|
'違規日期_起=' . substr(str_replace('-', '/', $data->start_time), 0, 10) . "\r\n" . |
|
'違規時間_起=' . substr(str_replace('-', '/', $data->start_time), 11, 8) . "\r\n"; |
|
|
|
if (!file_exists($savePath)) { |
|
mkdir($savePath, 0777, true); |
|
} |
|
$iniFile = fopen(($savePath . '\\' . $iniFileName), "w+"); |
|
|
|
$iniData = iconv('UTF-8', 'Big5', $iniData); |
|
// dd($iniDataF); |
|
// $iniData = iconv('UTF-8', 'Big5', "$iniData"); |
|
// $iniData = utf8_decode($iniData); |
|
// $iniData = iconv('UTF-8', 'ISO 8859-1', "$iniData" ); |
|
// iconv('UTF-8', 'GBK//IGNORE', "$iniData"); |
|
// $iniFile = iconv('UTF-8', 'windows-1252', $iniFile); |
|
|
|
// fwrite($iniFile, "$iniDataF"); |
|
fwrite($iniFile, "$iniData"); |
|
|
|
fclose($iniFile); |
|
if (!file_exists($saveclientPath)) { |
|
mkdir($saveclientPath, 0777, true); |
|
} |
|
// 第二路徑 |
|
$iniFile = fopen(($saveclientPath . '\\' . $iniFileName), "w+"); |
|
fwrite($iniFile, "$iniData"); |
|
fclose($iniFile); |
|
// 複製合成照片到指定路徑 |
|
|
|
copy($mergePhotoPath, $savePath . '\\' . str_replace('txt', 'jpg', $iniFileName)); |
|
copy($mergePhotoPath, $saveclientPath . '\\' . str_replace('txt', 'jpg', $iniFileName)); |
|
} |
|
|
|
|
|
#endregion |
|
|
|
#region 下載ZIP |
|
function downloadZipPicture(Request $request) |
|
{ |
|
set_time_limit(0); |
|
ini_set('memory_limit', '2048M'); |
|
$device = explode(',', auth("api")->user()->device) ?? [1]; |
|
|
|
if (isset($request->searchByFromdate)) |
|
$searchByFromdate = $request->searchByFromdate; |
|
if (isset($request->searchByTodate)) |
|
$searchByTodate = $request->searchByTodate; |
|
if (isset($request->location)) |
|
$serialnumber = $request->location; |
|
if (isset($request->carnumber)) |
|
$carnumber = $request->carnumber; |
|
if (isset($request->processcheck)) |
|
$processcheck = $request->processcheck; |
|
else $processcheck = 1; |
|
|
|
$records = Interval::query(); |
|
$records->where('location', 'not like', '%測試%'); |
|
$records->whereIn('serialnumber', $device); |
|
$records->where('processcheck', $processcheck); |
|
if (isset($searchByFromdate)) |
|
$records->where('datatime', ">", $searchByFromdate . ' 00:00:00'); |
|
else { |
|
$records->where('datatime', ">", Carbon::now()->subMonths(2)); |
|
$searchByFromdate = ''; |
|
} |
|
if (isset($searchByTodate)) |
|
$records->where('datatime', "<", $searchByTodate . ' 23:59:59'); |
|
else $searchByTodate = ''; |
|
if (isset($serialnumber)) |
|
$records->where('serialnumber', $request->location); |
|
if (isset($carnumber)) |
|
$records->where('carnumber', 'like', '%' . $carnumber . '%'); |
|
$records = $records->pluck("picture"); |
|
for ($i = 0; $i < count($records); $i++) { |
|
$records[$i] = storage_path("app\\ParsingFiles\\" . str_replace('*', '\\', $records[$i])); |
|
} |
|
$fileName = $this->downloadZip($records, $request->location, $searchByFromdate, $searchByTodate, $processcheck); |
|
|
|
if (file_exists($fileName)) { |
|
ExportFiles::create([ |
|
'name' => $fileName, |
|
'path' => 'public', |
|
'type' => 'zip', |
|
'status' => '1', |
|
'remark' => "區間-下載ZIP", |
|
'user_id' => auth('api')->user()->id, |
|
]); |
|
return $fileName; |
|
} else return "沒有檔案"; |
|
} |
|
|
|
public function downloadZip($files, $serialnumber, $searchByFromdate, $searchByTodate, $processcheck) |
|
{ |
|
set_time_limit(0); |
|
ini_set('memory_limit', '2048M'); |
|
try { |
|
foreach (glob(public_path() . '\*.zip') as $file) { |
|
unlink($file); |
|
} |
|
} catch (\Throwable $th) { |
|
//throw $th; |
|
} |
|
|
|
$zip = new ZipArchive; |
|
$rand = Str::random(5); |
|
$fileName = "_$rand.zip"; |
|
if (isset($searchByTodate)) |
|
$fileName = str_replace('-', '', $searchByTodate) . $fileName; |
|
if (isset($searchByFromdate)) |
|
$fileName = str_replace('-', '', $searchByFromdate) . "_" . $fileName; |
|
if (isset($serialnumber)) |
|
$fileName = $serialnumber . "_" . $fileName; |
|
if (isset($processcheck)) { |
|
if ($processcheck == 1) |
|
$fileName = "MS_OK_" . $fileName; |
|
if ($processcheck == 2) |
|
$fileName = "MS_X_" . $fileName; |
|
} |
|
|
|
if ($zip->open(public_path($fileName), ZipArchive::CREATE) === TRUE) { |
|
foreach ($files as $file) { |
|
try { |
|
$name = explode("\\", $file); |
|
$iniPath = str_replace('.jpg', '.ini', $file); |
|
$iniName = explode("\\", $iniPath); |
|
if (end($name) != '') { |
|
$zip->addFile($file, end($name)); |
|
$zip->addFile($iniPath, end($iniName)); |
|
} |
|
} catch (\Throwable $th) { |
|
//throw $th; |
|
Log::error($th); |
|
} |
|
} |
|
$zip->close(); |
|
} |
|
|
|
// response()->download(public_path($fileName))->deleteFileAfterSend(true); |
|
return "$fileName"; |
|
} |
|
#endregion |
|
|
|
}
|
|
|