diff --git a/app/Http/Controllers/Admin/DeviceController.php b/app/Http/Controllers/Admin/DeviceController.php index 8e2b98a..47e9185 100644 --- a/app/Http/Controllers/Admin/DeviceController.php +++ b/app/Http/Controllers/Admin/DeviceController.php @@ -36,7 +36,7 @@ class DeviceController extends Controller 'device_replace', 'device_remarks', 'operator_id', - 'ope_auth1', // ← ここもソートできるなら追加 + 'ope_auth1', ]; if (!in_array($sort, $sortable)) { diff --git a/app/Http/Controllers/Admin/PplaceController.php b/app/Http/Controllers/Admin/PplaceController.php index a9a4745..cb1b4a2 100644 --- a/app/Http/Controllers/Admin/PplaceController.php +++ b/app/Http/Controllers/Admin/PplaceController.php @@ -30,96 +30,135 @@ class PplaceController extends Controller return view('admin.pplace.list', $inputs); } + /** + * 新規登録(画面/処理) + */ public function add(Request $request) { - $inputs = [ - 'pplace_number' => $request->input('pplace_number'), - 'pplace_remarks' => $request->input('pplace_remarks'), - 'operator_id' => $request->input('operator_id'), + if ($request->isMethod('get')) { + // 新規時:空のレコードとオペレーターリストを渡す + return view('admin.pplace.add', [ + 'isEdit' => false, + 'record' => new Pplace(), + 'operators' => Ope::getList(), + ]); + } + + // POST時:バリデーション + $rules = [ + 'pplace_number' => 'required|string|max:255', + 'pplace_remarks' => 'nullable|string|max:255', + 'operator_id' => 'nullable|integer', + ]; + $messages = [ + 'pplace_number.required' => '駐輪場所番号は必須です。', ]; - - $inputs['operators'] = Ope::getList(); // - if ($request->isMethod('POST')) { - $validator = Validator::make($inputs, [ - 'pplace_number' => 'required|string|max:255', - 'pplace_remarks' => 'nullable|string|max:255', - 'operator_id' => 'nullable|integer', - ]); - - if (!$validator->fails()) { - DB::transaction(function () use ($inputs) { - $pplace = new Pplace(); - $pplace->fill($inputs); - $pplace->save(); - }); - return redirect()->route('pplaces')->with('success', '登録しました。'); - } else { - $inputs['errorMsg'] = $this->__buildErrorMessasges($validator); - } + $validator = Validator::make($request->all(), $rules, $messages); + + if ($validator->fails()) { + return redirect()->back() + ->withErrors($validator) + ->withInput() + ->with(['operators' => Ope::getList()]); } - return view('admin.pplace.add', $inputs); + // トランザクションで登録処理 + DB::transaction(function () use ($request) { + $new = new Pplace(); + $new->fill($request->only(['pplace_number', 'pplace_remarks', 'operator_id'])); + $new->save(); + }); + + return redirect()->route('pplaces')->with('success', '登録しました。'); } - public function edit(Request $request, $id, $view = '') + + /** + * 編集(画面/処理) + */ + public function edit(Request $request, $id) { - + // 該当データ取得 $record = Pplace::find($id); - - if (!$record) abort(404); - - $data = $record->toArray(); - $data['operators'] = Ope::getList(); - - - if ($request->isMethod('POST')) { - $inputs = $request->all(); - $validator = Validator::make($inputs, [ - 'pplace_number' => 'required|string|max:255', - 'pplace_remarks' => 'nullable|string|max:255', - 'operator_id' => 'nullable|integer', - ]); - - $data = array_merge($data, $inputs); - - if (!$validator->fails()) { - DB::transaction(function () use ($record, $inputs) { - $record->fill($inputs); - $record->save(); - }); - return redirect()->route('pplaces')->with('success', '更新成功'); - } else { - $data['errorMsg'] = $this->__buildErrorMessasges($validator); - } + if (!$record) { + abort(404); } - return view($view ?: 'admin.pplace.edit', $data); + // オペレーターリスト取得(常に渡す) + $operators = Ope::getList(); + + if ($request->isMethod('get')) { + // 編集画面表示 + return view('admin.pplace.edit', [ + 'isEdit' => true, + 'record' => $record, + 'operators' => $operators, + ]); + } + + // POST時:バリデーション + $rules = [ + 'pplace_number' => 'required|string|max:255', + 'pplace_remarks' => 'nullable|string|max:255', + 'operator_id' => 'nullable|integer', + ]; + $messages = [ + 'pplace_number.required' => '駐輪場所番号は必須です。', + ]; + + $validator = Validator::make($request->all(), $rules, $messages); + + if ($validator->fails()) { + return redirect()->back() + ->withErrors($validator) + ->withInput() + ->with(['operators' => $operators]); + } + + // 更新処理 + DB::transaction(function () use ($request, $record) { + $record->fill($request->only(['pplace_number', 'pplace_remarks', 'operator_id'])); + $record->save(); + }); + + return redirect()->route('pplaces')->with('success', '更新しました。'); } - public function info(Request $request, $id) - { - return $this->edit($request, $id, 'admin.pplace.info'); - } + /** + * 削除(単一/複数対応) + */ public function delete(Request $request) { - $arr_pk = $request->get('pk'); + $ids = []; - if ($arr_pk) { - $ids = is_array($arr_pk) ? $arr_pk : [$arr_pk]; - - if (Pplace::deleteByPk($ids)) { - return redirect()->route('pplaces')->with('success', __("削除成功しました。")); - } else { - return redirect()->route('pplaces')->with('error', __('削除に失敗しました。')); - } + // 単一削除(id) + if ($request->filled('id')) { + $ids[] = (int) $request->input('id'); } - return redirect()->route('pplaces')->with('error', __('削除するデータを選択してください。')); + // 複数削除(チェックボックス pk[]) + if (is_array($request->input('pk'))) { + $ids = array_merge($ids, $request->input('pk')); + } + + // 重複除去 & 数値変換 + $ids = array_values(array_unique(array_map('intval', $ids))); + + // 対象未選択 + if (empty($ids)) { + return back()->with('error', '削除対象が選択されていません。'); + } + + // 削除実行 + Pplace::whereIn('pplace_id', $ids)->delete(); + + return redirect()->route('pplaces')->with('success', '削除しました。'); } + public function export() { $filename = '駐輪車室マスタ' . now()->format('YmdHis') . '.csv'; diff --git a/app/Http/Controllers/Admin/PsectionController.php b/app/Http/Controllers/Admin/PsectionController.php index c687597..b827ad8 100644 --- a/app/Http/Controllers/Admin/PsectionController.php +++ b/app/Http/Controllers/Admin/PsectionController.php @@ -46,8 +46,8 @@ class PsectionController extends Controller if ($request->isMethod('get')) { // GET:新規画面を表示 return view('admin.psection.add', [ - 'isEdit' => false, // フォーム判定用 - 'record' => new Psection(), // ← ★★ これを渡すことで $record が使える + 'isEdit' => false, + 'record' => new Psection(), ]); } diff --git a/app/Http/Controllers/Admin/PtypeController.php b/app/Http/Controllers/Admin/PtypeController.php index 23569e4..a98c34d 100644 --- a/app/Http/Controllers/Admin/PtypeController.php +++ b/app/Http/Controllers/Admin/PtypeController.php @@ -14,23 +14,50 @@ class PtypeController extends Controller { public function list(Request $request) { + // 受け取る入力値 $inputs = [ - 'isMethodPost' => 0, + 'isMethodPost' => $request->isMethod('post') ? 1 : 0, 'isExport' => 0, - 'sort' => $request->input('sort', ''), - 'sort_type' => $request->input('sort_type', ''), + 'sort' => $request->input('sort', 'ptype_id'), // デフォルト: ID + 'sort_type' => strtolower($request->input('sort_type', 'asc')), 'page' => $request->get('page', 1), - ]; - $inputs['isMethodPost'] = $request->isMethod('post'); - $inputs['list'] = Ptype::search($inputs); + // 許可するソート可能カラム + $allowedSortColumns = [ + 'ptype_id', + 'ptype_subject', + 'floor_sort', + 'created_at', + ]; + + // 検索クエリ作成 + $query = \App\Models\Ptype::query(); + + // ソート処理 + if (in_array($inputs['sort'], $allowedSortColumns, true)) { + $sortType = in_array($inputs['sort_type'], ['asc', 'desc'], true) + ? $inputs['sort_type'] + : 'asc'; + + $query->orderBy($inputs['sort'], $sortType); + } else { + + $query->orderBy('ptype_id', 'asc'); + } + + // ページネーション + $inputs['list'] = $query->paginate(20); + + // ページが超過している場合リダイレクト if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) { return redirect()->route('ptypes'); } + // 画面へ return view('admin.ptypes.list', $inputs); } + /** * 新規登録(画面/処理) diff --git a/app/Http/Controllers/Admin/RegularTypeController.php b/app/Http/Controllers/Admin/RegularTypeController.php index a9e3e49..9c4fd89 100644 --- a/app/Http/Controllers/Admin/RegularTypeController.php +++ b/app/Http/Controllers/Admin/RegularTypeController.php @@ -131,7 +131,7 @@ class RegularTypeController extends Controller $record->save(); }); - $request->session()->flash('success', __('更新に成功しました')); + $request->session()->flash('success', __('更新しました。')); return redirect()->route('regular_types'); } diff --git a/app/Http/Controllers/Admin/TermsController.php b/app/Http/Controllers/Admin/TermsController.php index 8ff99b3..b2861b9 100644 --- a/app/Http/Controllers/Admin/TermsController.php +++ b/app/Http/Controllers/Admin/TermsController.php @@ -55,7 +55,7 @@ class TermsController extends Controller ]); Term::create($validated); - return redirect()->route('terms')->with('success', '利用規約が登録されました'); + return redirect()->route('terms')->with('success', '登録しました。'); } // 都市の選択肢を取得 $cities = City::pluck('city_name', 'city_id'); @@ -82,7 +82,7 @@ class TermsController extends Controller ]); $term->update($validated); - return redirect()->route('terms')->with('success', '利用規約が更新されました'); + return redirect()->route('terms')->with('success', '更新しました。'); } @@ -113,7 +113,7 @@ class TermsController extends Controller $deleted = Term::destroy($ids); if ($deleted > 0) { - return redirect()->route('terms')->with('success', __('削除成功しました。')); + return redirect()->route('terms')->with('success', __('削除しました。')); } else { return redirect()->route('terms')->with('error', __('削除に失敗しました。')); } diff --git a/app/Http/Controllers/Admin/ZoneController.php b/app/Http/Controllers/Admin/ZoneController.php index 7228767..a7f0920 100644 --- a/app/Http/Controllers/Admin/ZoneController.php +++ b/app/Http/Controllers/Admin/ZoneController.php @@ -6,6 +6,11 @@ use App\Http\Controllers\Controller; use Illuminate\Http\Request; use App\Models\Zone; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Validator; +use App\Models\Park; +use App\Models\Ptype; +use App\Models\Psection; + class ZoneController extends Controller { @@ -20,7 +25,7 @@ class ZoneController extends Controller // ソート設定 $sort = $request->input('sort', 'zone_id'); - $sort_type = $request->input('sort_type', 'desc'); + $sort_type = $request->input('sort_type', 'asc'); // ベースクエリ $query = Zone::query(); @@ -50,8 +55,8 @@ class ZoneController extends Controller // === 下拉选单用の一覧データ === $parkList = DB::table('park')->pluck('park_name', 'park_id'); - $ptypeList = DB::table('ptype')->pluck('ptype_id', 'ptype_id'); // 暂时显示 ID - $psectionList = DB::table('psection')->pluck('psection_id', 'psection_id'); // 暂时显示 ID + $ptypeList = DB::table('ptype')->pluck('ptype_subject', 'ptype_id'); + $psectionList = DB::table('psection')->pluck('psection_subject', 'psection_id'); return view('admin.zones.list', compact( 'zones', 'sort', 'sort_type', @@ -59,65 +64,172 @@ class ZoneController extends Controller )); } - /** - * 新規登録 + * 新規登録(画面/処理) */ public function add(Request $request) { - if ($request->isMethod('post')) { - $data = $this->validateZone($request); - Zone::create($data); + if ($request->isMethod('get')) { + $parkList = DB::table('park')->pluck('park_name', 'park_id'); + $ptypeList = DB::table('ptype')->pluck('ptype_subject', 'ptype_id'); + $psectionList = DB::table('psection')->pluck('psection_subject', 'psection_id'); - return redirect()->route('zones') - ->with('success', 'ゾーンを登録しました'); + + return view('admin.zones.add', [ + 'isEdit' => false, + 'record' => new Zone(), + 'parkList' => $parkList, + 'ptypeList' => $ptypeList, + 'psectionList' => $psectionList, + ]); } - $zone = new Zone(); - return view('admin.zones.add', compact('zone')); - } + // ▼ POST時:バリデーション + $rules = [ + 'park_id' => 'required|integer', + 'ptype_id' => 'required|integer', + 'psection_id' => 'required|integer', + 'zone_name' => 'required|string|max:255', + 'zone_number' => 'nullable|integer|min:0', + 'zone_standard' => 'nullable|integer|min:0', + 'zone_tolerance' => 'nullable|integer|min:0', + 'zone_sort' => 'nullable|integer|min:0', + ]; - /** - * 編集 - */ - public function edit($id, Request $request) - { - $zone = Zone::findOrFail($id); + $messages = [ + 'park_id.required' => '駐輪場は必須です。', + 'ptype_id.required' => '駐輪分類は必須です。', + 'psection_id.required' => '車種区分は必須です。', + 'zone_name.required' => 'ゾーン名は必須です。', + ]; - if ($request->isMethod('post')) { - $data = $this->validateZone($request); - $zone->update($data); + $validator = Validator::make($request->all(), $rules, $messages); - return redirect()->route('zones') - ->with('success', 'ゾーンを更新しました'); + if ($validator->fails()) { + return redirect()->back()->withErrors($validator)->withInput(); } - return view('admin.zones.edit', compact('zone')); + // ▼ 登録処理 + DB::transaction(function () use ($request) { + $new = new Zone(); + $new->fill($request->only([ + 'park_id', + 'ptype_id', + 'psection_id', + 'zone_name', + 'zone_number', + 'zone_standard', + 'zone_tolerance', + 'zone_sort', + ])); + $new->save(); + }); + + return redirect()->route('zones')->with('success', '登録しました。'); } /** - * 詳細表示 + * 編集(画面/処理) */ - public function info($id) + public function edit(Request $request, $id) { - $zone = Zone::findOrFail($id); + // 該当データ取得 + $record = Zone::find($id); + if (!$record) { + abort(404); + } - return view('admin.zones.info', compact('zone')); + $parkList = DB::table('park')->pluck('park_name', 'park_id'); + $ptypeList = DB::table('ptype')->pluck('ptype_subject', 'ptype_id'); + $psectionList = DB::table('psection')->pluck('psection_subject', 'psection_id'); + + + if ($request->isMethod('get')) { + // 編集画面表示 + return view('admin.zones.edit', [ + 'isEdit' => true, + 'record' => $record, + 'parkList' => $parkList, + 'ptypeList' => $ptypeList, + 'psectionList' => $psectionList, + ]); + } + + // ▼ POST時:バリデーション + $rules = [ + 'park_id' => 'required|integer', + 'ptype_id' => 'required|integer', + 'psection_id' => 'required|integer', + 'zone_name' => 'required|string|max:255', + 'zone_number' => 'nullable|integer|min:0', + 'zone_standard' => 'nullable|integer|min:0', + 'zone_tolerance' => 'nullable|integer|min:0', + 'zone_sort' => 'nullable|integer|min:0', + ]; + + $messages = [ + 'park_id.required' => '駐輪場は必須です。', + 'ptype_id.required' => '駐輪分類は必須です。', + 'psection_id.required' => '車種区分は必須です。', + 'zone_name.required' => 'ゾーン名は必須です。', + ]; + + $validator = Validator::make($request->all(), $rules, $messages); + + if ($validator->fails()) { + return redirect()->back()->withErrors($validator)->withInput(); + } + + // ▼ 更新処理 + DB::transaction(function () use ($request, $record) { + $record->fill($request->only([ + 'park_id', + 'ptype_id', + 'psection_id', + 'zone_name', + 'zone_number', + 'zone_standard', + 'zone_tolerance', + 'zone_sort', + ])); + $record->save(); + }); + + return redirect()->route('zones')->with('success', '更新しました。'); } /** - * 削除 + * 削除(単一/複数対応) */ public function delete(Request $request) { - $id = $request->input('id'); - if ($id) { - Zone::destroy($id); - return redirect()->route('zones')->with('success', 'ゾーンを削除しました'); + $ids = []; + + // 単一削除(id 指定) + if ($request->filled('id')) { + $ids[] = (int) $request->input('id'); } - return redirect()->route('zones')->with('error', '削除対象が指定されていません'); + + // 複数削除(チェックボックス pk[]) + if (is_array($request->input('pk'))) { + $ids = array_merge($ids, $request->input('pk')); + } + + // 重複除去 & 数値変換 + $ids = array_values(array_unique(array_map('intval', $ids))); + + // 削除対象がない場合 + if (empty($ids)) { + return back()->with('error', '削除対象が選択されていません。'); + } + + // 削除実行 + Zone::whereIn('zone_id', $ids)->delete(); + + return redirect()->route('zones')->with('success', '削除しました。'); } + /** * バリデーション共通化 */ diff --git a/app/Models/Zone.php b/app/Models/Zone.php index 3d3e94d..180c4f2 100644 --- a/app/Models/Zone.php +++ b/app/Models/Zone.php @@ -29,6 +29,7 @@ class Zone extends Model */ protected $fillable = [ 'park_id', + 'park_name', 'ptype_id', 'psection_id', 'zone_name', @@ -41,4 +42,19 @@ class Zone extends Model 'created_at', 'updated_at', ]; + public function park() + { + return $this->belongsTo(Park::class, 'park_id', 'park_id'); + } + + public function ptype() + { + return $this->belongsTo(Ptype::class, 'ptype_id', 'ptype_id'); + } + public function psection() + { + return $this->belongsTo(Psection::class, 'psection_id', 'psection_id'); + } + + } diff --git a/app/Utils.php b/app/Utils.php index aa251f4..a576cd5 100644 --- a/app/Utils.php +++ b/app/Utils.php @@ -20,7 +20,8 @@ use Illuminate\Support\Facades\Hash; class Utils { // ページあたりのアイテム数(旧システムから継承) - const item_per_page = 50; + // const item_per_page = 50; + const item_per_page = 20; // 画像保存パス(旧システムから継承) const image_path = 'storage/images/'; diff --git a/resources/views/admin/contract_allowable_cities/list.blade.php b/resources/views/admin/contract_allowable_cities/list.blade.php index a161386..7f44bbe 100644 --- a/resources/views/admin/contract_allowable_cities/list.blade.php +++ b/resources/views/admin/contract_allowable_cities/list.blade.php @@ -58,7 +58,7 @@