238 lines
9.0 KiB
PHP
238 lines
9.0 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Admin;
|
||
|
||
use Illuminate\Http\Request;
|
||
use App\Http\Controllers\Controller;
|
||
use Illuminate\Support\Facades\Validator;
|
||
use Illuminate\Support\Facades\DB;
|
||
use App\Models\City;
|
||
|
||
class CityController extends Controller
|
||
{
|
||
public function list(Request $request)
|
||
{
|
||
$sort = $request->input('sort', 'city_id');
|
||
$sortType = $request->input('sort_type', 'asc');
|
||
$page = $request->get('page', 1);
|
||
|
||
$menuAccessService = app(\App\Services\MenuAccessService::class);
|
||
|
||
// メニューアクセス制御: 非ソーリンユーザーは所属自治体のみ表示
|
||
$query = City::query();
|
||
if (!$menuAccessService->isSorin()) {
|
||
$operator = auth()->user();
|
||
if ($operator && isset($operator->management_id)) {
|
||
$query->where('management_id', $operator->management_id);
|
||
}
|
||
}
|
||
|
||
if ($request->filled('city_name')) {
|
||
$query->where('city_name', 'like', '%' . $request->input('city_name') . '%');
|
||
}
|
||
|
||
// ソート処理
|
||
if (!empty($sort)) {
|
||
$query->orderBy($sort, $sortType);
|
||
}
|
||
|
||
$list = $query->paginate(20);
|
||
|
||
// インデックス超過処理
|
||
if ($list->total() > 0 && $page > $list->lastPage()) {
|
||
return redirect()->route('city', [
|
||
'sort' => $sort,
|
||
'sort_type' => $sortType,
|
||
]);
|
||
}
|
||
|
||
return view('admin.CityMaster.list', [
|
||
'isMethodPost' => $request->isMethod('post'),
|
||
'sort' => $sort,
|
||
'sort_type' => $sortType,
|
||
'list' => $list,
|
||
'page' => $page,
|
||
]);
|
||
}
|
||
|
||
public function add(Request $request)
|
||
{
|
||
$inputs = [
|
||
'city_name' => '',
|
||
'print_layout' => '',
|
||
'city_user' => '',
|
||
'city_remarks' => '',
|
||
];
|
||
|
||
if ($request->isMethod('POST')) {
|
||
$rules = [
|
||
'city_name' => ['required', 'string', 'max:10', 'regex:/^[^ -~。-゚]+$/u'],
|
||
'print_layout' => ['required', 'string', 'max:10', 'regex:/^[^ -~。-゚]+$/u'],
|
||
'city_user' => ['required', 'string', 'max:10', 'regex:/^[^ -~。-゚]+$/u'],
|
||
'city_remarks' => ['nullable', 'string', 'max:20'],
|
||
];
|
||
$messages = [
|
||
'city_name.required' => '市区名は必須です。',
|
||
'city_name.regex' => '市区名は全角で入力してください。',
|
||
'print_layout.required' => '印字レイアウトファイルは必須です。',
|
||
'print_layout.regex' => '印字レイアウトファイルは全角で入力してください。',
|
||
'city_user.required' => '顧客M入力不要フィールドIDは必須です。',
|
||
'city_user.regex' => '顧客M入力不要フィールドIDは全角で入力してください。',
|
||
'city_remarks.max' => '備考は20文字以内で入力してください。',
|
||
];
|
||
$validator = Validator::make($request->all(), $rules, $messages);
|
||
|
||
$inputs = array_merge($inputs, $request->all());
|
||
|
||
if (!$validator->fails()) {
|
||
$maxId = DB::table('city')->max('city_id');
|
||
$newCityId = $maxId ? $maxId + 1 : 1;
|
||
|
||
$city = new City();
|
||
$city->city_id = $newCityId;
|
||
$city->fill($request->only([
|
||
'city_name',
|
||
'print_layout',
|
||
'city_user',
|
||
'city_remarks',
|
||
]));
|
||
|
||
if ($city->save()) {
|
||
$request->session()->flash('success', __('登録に成功しました'));
|
||
return redirect()->route('city');
|
||
} else {
|
||
$request->session()->flash('error', __('登録に失敗しました'));
|
||
}
|
||
} else {
|
||
$inputs['errorMsg'] = $validator->errors()->all();
|
||
}
|
||
}
|
||
|
||
return view('admin.CityMaster.add', $inputs);
|
||
}
|
||
|
||
public function edit(Request $request, $pk, $view = '')
|
||
{
|
||
$city = City::find($pk);
|
||
if (!$city) {
|
||
abort(404);
|
||
}
|
||
|
||
// メニューアクセス制御確認
|
||
$menuAccessService = app(\App\Services\MenuAccessService::class);
|
||
if (!$menuAccessService->canAccessCity($city->city_id)) {
|
||
abort(403, 'この自治体へのアクセス権限がありません。');
|
||
}
|
||
|
||
if ($request->isMethod('POST')) {
|
||
$rules = [
|
||
'city_name' => ['required', 'string', 'max:10', 'regex:/^[^ -~。-゚]+$/u'],
|
||
'print_layout' => ['required', 'string', 'max:10', 'regex:/^[^ -~。-゚]+$/u'],
|
||
'city_user' => ['required', 'string', 'max:10', 'regex:/^[^ -~。-゚]+$/u'],
|
||
'city_remarks' => ['nullable', 'string', 'max:20'],
|
||
];
|
||
$messages = [
|
||
'city_name.required' => '市区名は必須です。',
|
||
'city_name.regex' => '市区名は全角で入力してください。',
|
||
'print_layout.required' => '印字レイアウトファイルは必須です。',
|
||
'print_layout.regex' => '印字レイアウトファイルは全角で入力してください。',
|
||
'city_user.required' => '顧客M入力不要フィールドIDは必須です。',
|
||
'city_user.regex' => '顧客M入力不要フィールドIDは全角で入力してください。',
|
||
'city_remarks.max' => '備考は20文字以内で入力してください。',
|
||
];
|
||
$validator = Validator::make($request->all(), $rules, $messages);
|
||
|
||
if (!$validator->fails()) {
|
||
$city->fill($request->only([
|
||
'city_name',
|
||
'print_layout',
|
||
'city_user',
|
||
'city_remarks',
|
||
]));
|
||
|
||
if ($city->save()) {
|
||
$request->session()->flash('success', __('更新に成功しました'));
|
||
return redirect()->route('city');
|
||
} else {
|
||
$request->session()->flash('error', __('更新に失敗しました'));
|
||
}
|
||
} else {
|
||
return view('admin.CityMaster.edit', [
|
||
'city' => $city,
|
||
'errorMsg' => $validator->errors()->all(),
|
||
]);
|
||
}
|
||
}
|
||
|
||
return view($view ?: 'admin.CityMaster.edit', [
|
||
'city' => $city,
|
||
]);
|
||
}
|
||
|
||
public function info(Request $request, $pk)
|
||
{
|
||
return $this->edit($request, $pk, 'CityMaster.info');
|
||
}
|
||
|
||
public function delete(Request $request)
|
||
{
|
||
$arr_pk = $request->get('pk');
|
||
if (!$arr_pk) {
|
||
return redirect()->route('city')->with('error', __('削除する市区を選択してください。'));
|
||
}
|
||
if (City::destroy($arr_pk)) {
|
||
return redirect()->route('city')->with('success', __("削除が完了しました。"));
|
||
} else {
|
||
return redirect()->route('city')->with('error', __('削除に失敗しました。'));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 自治体ダッシュボード
|
||
*/
|
||
public function dashboard(Request $request, $city_id)
|
||
{
|
||
$city = City::find($city_id);
|
||
if (!$city) {
|
||
return redirect()->route('city')->with('error', '指定された自治体が見つかりません。');
|
||
}
|
||
|
||
// この自治体に関連する駐輪場データを取得
|
||
$parks = \App\Models\Park::where('city_id', $city_id)->get();
|
||
$parkIds = $parks->pluck('park_id')->toArray();
|
||
|
||
// この自治体の統計情報を取得
|
||
$contractsCount = 0;
|
||
$usersCount = 0;
|
||
$waitingCount = 0;
|
||
|
||
if (!empty($parkIds)) {
|
||
// 契約数を取得
|
||
$contractsCount = \App\Models\RegularContract::whereIn('park_id', $parkIds)->count();
|
||
|
||
// この自治体の駐輪場で契約しているユニークユーザー数を取得
|
||
$userIds = \App\Models\RegularContract::whereIn('park_id', $parkIds)
|
||
->distinct()
|
||
->pluck('user_id')
|
||
->toArray();
|
||
$usersCount = count(array_filter($userIds));
|
||
|
||
// 予約待ち人数を取得(valid_flag = 1 かつ reserve_order が設定されているもの)
|
||
$waitingCount = DB::table('reserve')
|
||
->whereIn('park_id', $parkIds)
|
||
->where('valid_flag', 1)
|
||
->whereNotNull('reserve_order')
|
||
->where('reserve_order', '>', 0)
|
||
->count();
|
||
}
|
||
|
||
$stats = [
|
||
'parks_count' => $parks->count(),
|
||
'contracts_count' => $contractsCount,
|
||
'users_count' => $usersCount,
|
||
'waiting_count' => $waitingCount,
|
||
];
|
||
|
||
return view('admin.CityMaster.dashboard', compact('city', 'parks', 'stats'));
|
||
}
|
||
} |