krgm.so-manager-dev.com/app/Http/Controllers/Admin/ManagerController.php
kin.rinzen 5c1b33cedc
All checks were successful
Deploy main / deploy (push) Successful in 21s
SWA-67/SWA-80/SWA-89 画面修正
2025-10-01 18:00:19 +09:00

250 lines
9.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Manager;
use App\Models\Park;
use App\Models\Device;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\StreamedResponse;
class ManagerController extends Controller
{
/** 一覧 */
public function list(Request $request)
{
$sortable = [
'manager_id','manager_name','manager_parkid','manager_tel',
'manager_alert1','manager_alert2','manager_quit_flag'
];
$sort = $request->input('sort', 'manager_id');
$sort_type = $request->input('sort_type', 'asc');
if (!in_array($sort, $sortable)) $sort = 'manager_id';
if (!in_array(strtolower($sort_type), ['asc','desc'])) $sort_type = 'asc';
$list = Manager::with(['park','device1','device2'])
->orderBy($sort, $sort_type)
->paginate(20);
return view('admin.managers.list', compact('list','sort','sort_type'));
}
/** 新規登録画面・登録処理 */
public function add(Request $request)
{
if ($request->isMethod('post')) {
$validated = $this->validated($request);
Manager::create($validated);
return redirect()
->route('managers')
->with('success', '登録しました。');
}
return view('admin.managers.add', $this->viewVars());
}
/** 編集GET:画面表示 / POST:更新) */
public function edit(Request $request, $id)
{
$manager = Manager::findOrFail($id);
if ($request->isMethod('post')) {
$validated = $this->validated($request);
$manager->update($validated);
return redirect()
->route('managers')
->with('success', '更新されました。');
}
return view('admin.managers.edit', $this->viewVars($manager));
}
/** 詳細(閲覧) */
public function info($manager_id)
{
$manager = Manager::with(['park','device1','device2'])->findOrFail($manager_id);
$view = $this->viewVars($manager);
return view('admin.managers.info', $view);
}
/** 一括削除(一覧・詳細・編集共通で pk[] を受ける) */
public function delete(Request $request)
{
$ids = (array) $request->input('pk', []);
if (!$ids) {
return back()->with('error', '削除対象が選択されていません。');
}
DB::transaction(fn() => Manager::whereIn('manager_id', $ids)->delete());
// 一覧画面へリダイレクト + 成功メッセージ
return redirect()
->route('managers')
->with('success', '削除しました。');
}
/** CSV出力 */
public function export(): StreamedResponse
{
$headers = [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename=managers.csv',
];
$columns = [
'manager_id','manager_name','manager_type','manager_parkid',
'manager_device1','manager_device2','manager_mail','manager_tel',
'manager_alert1','manager_alert2','manager_quit_flag','manager_quitday'
];
return response()->stream(function () use ($columns) {
$out = fopen('php://output', 'w');
fwrite($out, "\xEF\xBB\xBF"); // BOM
fputcsv($out, $columns);
Manager::chunk(500, function ($rows) use ($out, $columns) {
foreach ($rows as $r) {
fputcsv($out, array_map(fn($c) => data_get($r, $c), $columns));
}
});
fclose($out);
}, 200, $headers);
}
/** CSVインポートinput name="file" */
public function import(Request $request)
{
if (!$request->hasFile('file')) {
return back()->with('error', 'CSVファイルを選択してください。');
}
$fp = fopen($request->file('file')->getRealPath(), 'r');
if (!$fp) return back()->with('error', 'CSVを読み込めませんでした。');
$header = fgetcsv($fp);
if (!$header) { fclose($fp); return back()->with('error', 'ヘッダ行が読み取れません。'); }
$required = [
'manager_id','manager_name','manager_type','manager_parkid',
'manager_device1','manager_device2','manager_mail','manager_tel',
'manager_alert1','manager_alert2','manager_quit_flag','manager_quitday'
];
foreach ($required as $c) {
if (!in_array($c, $header)) { fclose($fp); return back()->with('error', "CSVに {$c} がありません。"); }
}
DB::beginTransaction();
try {
while (($row = fgetcsv($fp)) !== false) {
$data = array_combine($header, $row); if (!$data) continue;
Manager::updateOrCreate(
['manager_id' => $data['manager_id']],
[
'manager_name' => $data['manager_name'] ?? null,
'manager_type' => $data['manager_type'] ?? null,
'manager_parkid' => $data['manager_parkid'] ?: null,
'manager_device1' => $data['manager_device1'] ?: null,
'manager_device2' => $data['manager_device2'] ?: null,
'manager_mail' => $data['manager_mail'] ?? null,
'manager_tel' => $data['manager_tel'] ?? null,
'manager_alert1' => (int)($data['manager_alert1'] ?? 0),
'manager_alert2' => (int)($data['manager_alert2'] ?? 0),
'manager_quit_flag' => (int)($data['manager_quit_flag'] ?? 0),
'manager_quitday' => $data['manager_quitday'] ?: null,
]
);
}
fclose($fp);
DB::commit();
return back()->with('success', 'インポートが完了しました。');
} catch (\Throwable $e) {
if (is_resource($fp)) fclose($fp);
DB::rollBack();
return back()->with('error', 'インポートに失敗しました:'.$e->getMessage());
}
}
/** バリデーション + 前処理 */
private function validated(Request $request): array
{
// 電話番号を全角に変換(半角入力があっても自動で全角に揃える)
$request->merge([
'manager_tel' => mb_convert_kana($request->input('manager_tel'), 'N') // 半角数字→全角数字
]);
// select の未選択 "" を null に補正
foreach (['manager_device2'] as $f) {
if ($request->input($f) === "") {
$request->merge([$f => null]);
}
}
return $request->validate([
'manager_name' => ['required','string','max:32'],
'manager_type' => ['required','string','max:10'],
'manager_parkid' => ['required','integer','exists:park,park_id'],
'manager_device1' => ['required','integer','exists:device,device_id'],
'manager_device2' => ['nullable','integer','exists:device,device_id'],
'manager_mail' => ['nullable','email','max:128'],
'manager_tel' => ['required','regex:/^[-]+$/u','max:13'], // 全角数字のみ
'manager_alert1' => ['nullable','boolean'],
'manager_alert2' => ['nullable','boolean'],
'manager_quit_flag' => ['required','in:0,1'],
'manager_quitday' => ['nullable','date'],
], [], [
'manager_name' => '駐輪場管理者名',
'manager_type' => '種別',
'manager_parkid' => '所属駐輪場ID',
'manager_device1' => '管理デバイス1',
'manager_device2' => '管理デバイス2',
'manager_mail' => 'メールアドレス',
'manager_tel' => '電話番号',
'manager_alert1' => 'アラート1送信',
'manager_alert2' => 'アラート2送信',
'manager_quit_flag' => '退職フラグ',
'manager_quitday' => '退職日',
]);
}
/** 画面に渡す変数を作る_form.blade.php が個別変数を参照するため) */
private function viewVars(?Manager $m = null): array
{
$parks = Park::orderBy('park_name')->pluck('park_name','park_id')->toArray();
$devices = Device::orderBy('device_subject')->pluck('device_subject','device_id')->toArray();
return [
// _form が参照する個別変数
'manager_id' => $m->manager_id ?? null,
'manager_name' => $m->manager_name ?? null,
'manager_type' => $m->manager_type ?? null,
'manager_parkid' => $m->manager_parkid ?? null,
'manager_device1' => $m->manager_device1 ?? null,
'manager_device2' => $m->manager_device2 ?? null,
'manager_mail' => $m->manager_mail ?? null,
'manager_tel' => $m->manager_tel ?? null,
'manager_alert1' => (int)($m->manager_alert1 ?? 0),
'manager_alert2' => (int)($m->manager_alert2 ?? 0),
'manager_quit_flag' => isset($m) ? (int)$m->manager_quit_flag : 0,
'manager_quitday' => isset($m) && $m->manager_quitday ? $m->manager_quitday->format('Y-m-d') : null,
// セレクトの候補
'parks' => $parks,
'devices' => $devices,
// _form で必要なフラグ各ビューで上書きしてもOK
'isEdit' => isset($m),
'isInfo' => false,
'record' => $m, // 互換用(あなた的 edit.blade.php で参照しているなら)
];
}
}