main_ou #12

Merged
go.unhi merged 14 commits from main_ou into main 2025-08-23 00:39:02 +09:00
63 changed files with 10372 additions and 489 deletions

1
.env
View File

@ -3,7 +3,6 @@ APP_ENV=local
APP_KEY=base64:ejLwJbt2bEXY9emPUmsurG+X1hzkjTxQQvq2/FO14RY= APP_KEY=base64:ejLwJbt2bEXY9emPUmsurG+X1hzkjTxQQvq2/FO14RY=
APP_DEBUG=true APP_DEBUG=true
APP_URL=https://krgm.so-manager-dev.com/ APP_URL=https://krgm.so-manager-dev.com/
APP_LOCALE=ja APP_LOCALE=ja
APP_FALLBACK_LOCALE=ja APP_FALLBACK_LOCALE=ja
APP_FAKER_LOCALE=ja_JP APP_FAKER_LOCALE=ja_JP

View File

@ -0,0 +1,20 @@
name: Deploy preview (main_ou)
on:
push:
branches: ["main_ou"]
workflow_dispatch:
concurrency:
group: deploy-main_ou
cancel-in-progress: true
jobs:
deploy:
runs-on: ["native"]
steps:
- uses: actions/checkout@v4
- name: Deploy to preview (main_ou)
env:
BRANCH: main_ou
run: /usr/local/bin/deploy_branch_simple.sh

View File

@ -1,14 +0,0 @@
name: Deploy krgm (auto)
on:
push:
branches: [ "main" ]
workflow_dispatch:
jobs:
deploy:
runs-on: [ "native" ]
steps:
- uses: actions/checkout@v4
- name: Deploy to server
run: /usr/local/bin/deploy_krgm.sh

10
app/AppModel.php Normal file
View File

@ -0,0 +1,10 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class AppModel extends Model
{
}

View File

@ -0,0 +1,139 @@
<?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)
{
$inputs = [
'isMethodPost' => $request->isMethod('post'),
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
];
$query = City::query();
if ($request->filled('city_name')) {
$query->where('city_name', 'like', '%' . $request->input('city_name') . '%');
}
if (!empty($inputs['sort'])) {
$query->orderBy($inputs['sort'], $inputs['sort_type'] ?? 'asc');
}
$inputs['list'] = $query->paginate(20);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
return redirect()->route('city');
}
return view('admin.CityMaster.list', $inputs);
}
public function add(Request $request)
{
$inputs = [
'city_name' => '',
'print_layout' => '',
'city_user' => '',
'city_remarks' => '',
];
if ($request->isMethod('POST')) {
$rules = [
'city_name' => 'required|string|max:255',
];
$validator = Validator::make($request->all(), $rules);
$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);
}
if ($request->isMethod('POST')) {
$rules = [
'city_name' => 'required|string|max:255',
];
$validator = Validator::make($request->all(), $rules);
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 && City::destroy($arr_pk)) {
return redirect()->route('city')->with('success', __("削除が完了しました。"));
} else {
return redirect()->route('city')->with('error', __('削除に失敗しました。'));
}
}
}

View File

@ -0,0 +1,115 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ContractorController extends Controller
{
/**
* 一覧表示GET/POST
*/
public function list(Request $request)
{
$q = DB::table('regular_contract as rc')
->select([
'rc.contract_id',
'rc.contract_qr_id',
'rc.user_id',
'rc.user_categoryid',
'rc.park_id',
'rc.contract_created_at',
'rc.contract_periods',
'rc.contract_periode',
'rc.tag_qr_flag',
'rc.contract_flag',
'rc.contract_cancel_flag',
'rc.contract_payment_day',
'rc.contract_money',
'rc.billing_amount',
'rc.contract_permission',
'rc.contract_manual',
'rc.contract_notice',
'p.park_name',
'u.user_name',
'u.user_phonetic',
'u.user_mobile',
'u.user_homephone',
'u.user_primemail',
'u.user_gender',
'u.user_birthdate',
'u.user_regident_zip',
'u.user_regident_pre',
'u.user_regident_city',
'u.user_regident_add',
'u.user_relate_zip',
'u.user_relate_pre',
'u.user_relate_city',
'u.user_relate_add',
'u.user_graduate',
'u.user_workplace',
'u.user_school',
'u.user_remarks',
// 他に必要なカラムもここに追加
])
->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
->leftJoin('user as u', 'rc.user_id', '=', 'u.user_id');
// 検索条件例
if ($request->filled('contract_id')) {
$q->where('rc.contract_id', $request->input('contract_id'));
}
if ($request->filled('name')) {
$q->where('u.user_name', 'like', '%' . $request->input('name') . '%');
}
// タグ・QR完全一致、空白なら絞り込まない
if ($request->filled('tag_qr_flag') && $request->input('tag_qr_flag') !== '') {
$q->where('rc.tag_qr_flag', $request->input('tag_qr_flag'));
}
// ソート処理
$sort = $request->input('sort', 'rc.contract_id');
$sortType = $request->input('sort_type', 'desc');
// カラム名のバリデーション(必要に応じて拡張)
$allowSorts = ['rc.contract_id'];
if (!in_array($sort, $allowSorts)) {
$sort = 'rc.contract_id';
}
$sortType = ($sortType === 'asc') ? 'asc' : 'desc';
$rows = $q->orderBy($sort, $sortType)->paginate(20)->withQueryString();
return view('admin.contractor.list', compact('rows', 'sort', 'sortType'));
}
/**
* 詳細表示
*/
public function info($id)
{
$contract = DB::table('regular_contract as rc')
->select([
'rc.*',
'p.park_name',
'u.user_name',
'u.user_phonetic',
'u.user_mobile',
'u.user_homephone',
'u.user_primemail',
'u.user_gender',
'u.user_birthdate',
'u.user_regident_city',
])
->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
->leftJoin('user as u', 'rc.user_id', '=', 'u.user_id')
->where('rc.contract_id', $id)
->first();
if (!$contract) { abort(404); }
return view('admin.contractor.info', compact('contract'));
}
}

View File

@ -0,0 +1,116 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ContractorListController extends Controller
{
/**
* 一覧表示GET/POST
*/
public function list(Request $request)
{
$q = DB::table('regular_contract as rc')
->select([
'rc.contract_id',
'rc.contract_qr_id',
'rc.user_id',
'rc.user_categoryid',
'rc.park_id',
'rc.contract_created_at',
'rc.contract_periods',
'rc.contract_periode',
'rc.tag_qr_flag',
'rc.contract_flag',
'rc.contract_cancel_flag',
'rc.contract_payment_day',
'rc.contract_money',
'rc.billing_amount',
'rc.contract_permission',
'rc.contract_manual',
'rc.contract_notice',
'p.park_name',
// userテーブルの正しいカラム名
'u.user_name',
'u.user_phonetic',
'u.user_mobile',
'u.user_homephone',
'u.user_primemail',
'u.user_gender',
'u.user_birthdate',
'u.user_regident_zip',
'u.user_regident_pre',
'u.user_regident_city',
'u.user_regident_add',
'u.user_relate_zip',
'u.user_relate_pre',
'u.user_relate_city',
'u.user_relate_add',
'u.user_graduate',
'u.user_workplace',
'u.user_school',
'u.user_remarks',
// 他に必要なカラムもここに追加
])
->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
->leftJoin('user as u', 'rc.user_id', '=', 'u.user_id');
// 検索条件例
if ($request->filled('contract_id')) {
$q->where('rc.contract_id', $request->input('contract_id'));
}
if ($request->filled('name')) {
$q->where('u.user_name', 'like', '%' . $request->input('name') . '%');
}
// タグ・QR完全一致、空白なら絞り込まない
if ($request->filled('tag_qr_flag') && $request->input('tag_qr_flag') !== '') {
$q->where('rc.tag_qr_flag', $request->input('tag_qr_flag'));
}
// ソート処理
$sort = $request->input('sort', 'rc.contract_id');
$sortType = $request->input('sort_type', 'desc');
// カラム名のバリデーション(必要に応じて拡張)
$allowSorts = ['rc.contract_id'];
if (!in_array($sort, $allowSorts)) {
$sort = 'rc.contract_id';
}
$sortType = ($sortType === 'asc') ? 'asc' : 'desc';
$rows = $q->orderBy($sort, $sortType)->paginate(20)->withQueryString();
return view('admin.contractor_list.list', compact('rows', 'sort', 'sortType'));
}
/**
* 詳細表示
*/
public function info($id)
{
$contract = DB::table('regular_contract as rc')
->select([
'rc.*',
'p.park_name',
'u.user_name',
'u.user_phonetic',
'u.user_mobile',
'u.user_homephone',
'u.user_primemail',
'u.user_gender',
'u.user_birthdate',
'u.user_regident_city',
])
->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
->leftJoin('user as u', 'rc.user_id', '=', 'u.user_id')
->where('rc.contract_id', $id)
->first();
if (!$contract) { abort(404); }
return view('admin.contractor.info', compact('contract'));
}
}

View File

@ -0,0 +1,192 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
class NewsController extends Controller
{
/** @var string テーブル名 */
protected string $table = 'news';
/** @var string 主キー列名 */
protected string $pk = 'news_id';
/**
* 現在ログイン中のオペレーターIDを取得
* @return int|null
*/
protected function currentOperatorId(): ?int
{
$u = auth()->user();
return $u->ope_id ?? $u->id ?? null;
}
/**
* 一覧表示GET/POST
* 検索条件kw本文/URL 部分一致、mode、open_datetime 範囲from/to
*/
public function list(Request $request)
{
// 一覧用クエリ(表示に必要な列のみ)
$q = DB::table($this->table)->select([
"{$this->pk} as id",
'news',
'mode',
'open_datetime',
'link_url',
'image1_filename',
'image2_filename',
'created_at',
'updated_at',
]);
// キーワード検索(本文/リンクURL
if ($kw = trim((string)$request->input('kw', ''))) {
$q->where(function($w) use ($kw) {
$w->where('news','like',"%{$kw}%")
->orWhere('link_url','like',"%{$kw}%");
});
}
// 表示モードで絞り込み0:非表示 / 1:公開 / 2:下書き など)
if ($request->filled('mode')) {
$q->where('mode', (int)$request->input('mode'));
}
// 公開日時の範囲指定
if ($request->filled('from')) { $q->where('open_datetime','>=',$request->input('from')); }
if ($request->filled('to')) { $q->where('open_datetime','<=',$request->input('to')); }
// 並び順:公開日時の降順 → 主キー降順
$rows = $q->orderByDesc('open_datetime')
->orderByDesc($this->pk)
->paginate(20)
->withQueryString();
return view('admin.news.list', compact('rows'));
}
/**
* 新規作成GET:フォーム表示 / POST:登録処理)
*/
public function add(Request $request)
{
if ($request->isMethod('post')) {
// 入力チェック
$v = $request->validate([
'news' => 'required|string',
'open_datetime' => 'nullable|date_format:Y-m-d H:i:s',
'link_url' => 'nullable|string|max:255',
'image1_filename' => 'nullable|string|max:255',
'image2_filename' => 'nullable|string|max:255',
'mode' => 'required|integer|min:0|max:9',
]);
// 登録
$now = now();
DB::table($this->table)->insert([
'news' => $v['news'],
'open_datetime' => $v['open_datetime'] ?? null,
'link_url' => $v['link_url'] ?? null,
'image1_filename' => $v['image1_filename'] ?? null,
'image2_filename' => $v['image2_filename'] ?? null,
'mode' => $v['mode'],
'created_at' => $now,
'updated_at' => $now,
'operator_id' => $this->currentOperatorId(),
]);
return redirect()->route('news')->with('success','ニュースを登録しました。');
}
// フォーム表示
return view('admin.news.add');
}
/**
* 編集GET:フォーム表示 / POST:更新処理)
* @param int $id ニュースID
*/
public function edit($id, Request $request)
{
// 対象データ取得
$news = DB::table($this->table)->where($this->pk, $id)->first();
if (!$news) { abort(404); }
if ($request->isMethod('post')) {
// 入力チェック
$v = $request->validate([
'news' => 'required|string',
'open_datetime' => 'nullable|date_format:Y-m-d H:i:s',
'link_url' => 'nullable|string|max:255',
'image1_filename' => 'nullable|string|max:255',
'image2_filename' => 'nullable|string|max:255',
'mode' => 'required|integer|min:0|max:9',
]);
// 更新
DB::table($this->table)->where($this->pk, $id)->update([
'news' => $v['news'],
'open_datetime' => $v['open_datetime'] ?? null,
'link_url' => $v['link_url'] ?? null,
'image1_filename' => $v['image1_filename'] ?? null,
'image2_filename' => $v['image2_filename'] ?? null,
'mode' => $v['mode'],
'updated_at' => now(),
'operator_id' => $this->currentOperatorId(),
]);
return redirect()->route('news_edit', ['id'=>$id])->with('success','更新しました。');
}
// フォーム表示
return view('admin.news.edit', compact('news'));
}
/**
* 詳細表示
* @param int $id ニュースID
*/
public function info($id)
{
// 詳細用に必要な列を選択
$news = DB::table($this->table)
->select([
"{$this->pk} as id",
'news','mode','open_datetime','link_url',
'image1_filename','image2_filename',
'created_at','updated_at','operator_id',
])->where($this->pk, $id)->first();
if (!$news) { abort(404); }
return view('admin.news.info', compact('news'));
}
/**
* 削除(単体 id または 複数 ids[] に対応)
*/
public function delete(Request $request)
{
// 削除対象IDの取得単体 or 複数)
$ids = $request->input('ids');
if (!$ids) {
$id = (int)$request->input('id');
if ($id > 0) { $ids = [$id]; }
}
// バリデーション:削除対象未選択
if (!is_array($ids) || empty($ids)) {
return back()->with('error', '削除対象が選択されていません。');
}
// 削除実行
DB::table($this->table)->whereIn($this->pk, $ids)->delete();
return back()->with('success','削除しました。');
}
}

View File

@ -0,0 +1,266 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\City;
use App\Http\Requests\ParkRequest;
use App\Models\Park;
use App\Utils;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Response;
class ParkController extends Controller
{
public function list(Request $request)
{
$query = \DB::table('park as p')
->leftJoin('city as c', 'p.city_id', '=', 'c.city_id')
->select([
'p.park_id',
'c.city_name',
'p.park_name',
'p.park_ruby',
'p.park_syllabary',
'p.park_adrs',
'p.park_close_flag',
'p.park_day',
'p.alert_flag',
'p.print_number',
'p.keep_alive',
]);
if ($request->filled('park_name')) {
$query->where('p.park_name', 'like', '%' . $request->input('park_name') . '%');
}
if ($request->filled('city_id')) {
$query->where('p.city_id', $request->input('city_id'));
}
if ($request->filled('sort')) {
$query->orderBy($request->input('sort'), $request->input('sort_type', 'asc'));
} else {
$query->orderBy('p.park_id', 'asc');
}
$parks = $query->paginate(20);
$cities = \DB::table('city')->orderBy('city_id')->get();
return view('admin.parks.list', compact('parks', 'cities'));
}
public function add(Request $request)
{
$cities = \DB::table('city')->orderBy('city_id')->get();
if ($request->isMethod('post')) {
// バリデーション(必要な項目だけ例示)
$validated = $request->validate([
'city_id' => 'required|integer',
'park_name' => 'required|string|max:255',
// 他の項目も必要に応じて追加
]);
// 保存処理
$park = new \App\Models\Park();
$park->fill($validated);
$park->save();
return redirect()->route('parks')->with('success', '登録しました');
}
return view('admin.parks.add', [
'cities' => $cities,
]);
}
public function edit(Request $request, $pk, $view = '')
{
$park = Park::getByPk($pk);
if (empty($pk) || empty($park)) {
abort('404');
}
$data = $park->getAttributes();
$dataList = $this->getDataDropList();
$data = array_merge($data, $dataList);
if ($request->isMethod('POST')) {
// ここをaddと同じバリデーションに変更
$validated = $request->validate([
'city_id' => 'required|integer',
'park_name' => 'required|string|max:255',
// 他の項目も必要に応じて追加
]);
\DB::transaction(function () use ($validated, &$type, $park) {
$park->fill($validated);
$park->save();
$type = true;
});
$request->session()->flash('success', __('更新に成功しました'));
return redirect()->route('parks');
}
if ($view != '') {
return view($view, $data);
}
return view('admin.parks.edit', [
'park' => $park,
'cities' => $dataList['cities'] ?? [],
// 必要な他の変数もここで渡す
]);
}
public function delete(Request $request)
{
$arr_pk = $request->get('pk');
if ($arr_pk) {
if (Park::deleteByPk($arr_pk)) {
return redirect()->route('parks')->with('success', __("削除が完了しました。"));
} else {
return redirect()->route('parks')->with('error', __('削除に失敗しました。'));
}
}
return redirect()->route('parks')->with('error', __('削除するユーザーを選択してください。'));
}
public function info(Request $request, $id)
{
return $this->edit($request, $id, 'admin.parks.info');
}
public function getDataDropList()
{
$data['cities'] = City::orderBy('city_id')->get();
return $data;
}
public function export(Request $request)
{
$headers = array(
"Content-type" => "text/csv;charset=UTF-8",
'Content-Encoding: UTF-8',
"Content-Disposition" => "attachment; filename=file.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
];
$dataExport = Park::search($inputs);
$columns = array(
__('駐輪場ID '),// 0
__('市区ID'),// 1
__('市区'),// 2
__('駐輪場名'),// 3
__('駐輪場ふりがな'),// 4
__('駐輪場五十音'),// 5
__('住所'),// 6
__('閉設フラグ'),// 7
__('閉設フラグ'),// 8
__('閉設日'),// 9
__('残警告チェックフラグ'),// 10
__('印字数'),// 11
__('最新キープアライブ')// 12
);
$filename = "駐輪場マスタ.csv";
$file = fopen($filename, 'w+');
fputcsv($file, $columns);
foreach ($dataExport as $items) {
fputcsv(
$file,
array(
$items->park_id,// 0
$items->city_id,// 1
!empty($items->getCity()) ? $items->getCity()->city_name : "",// 2
$items->park_name, // 3
$items->park_ruby, // 4
$items->park_syllabary, // 5
$items->park_adrs, // 6
$items->park_close_flag,// 7
$items->getParkCloseFlagDisplay(),// 8
$items->park_day,// 9
$items->alert_flag,// 10
$items->print_number,// 11
$items->keep_alive// 12
)
);
}
fclose($file);
return Response::download($filename, $filename, $headers);
}
public function import(Request $request)
{
$file = $request->file('file');
if (!empty($file)) {
$data = Utils::csvToArray($file);
$type = 1;
$msg = '';
$record = 0;
DB::beginTransaction();
try {
Park::query()->delete();
$col = 13;
foreach ($data as $key => $items) {
$record = $key + 2;
if (count($items) == $col) {
$row = new Park();
$row->park_id = $items[0];
$row->city_id = $items[1];
$row->park_name = $items[3];
$row->park_ruby = $items[4];
$row->park_syllabary = $items[5];
$row->park_adrs = $items[6];
$row->park_close_flag = $items[7];
$row->park_day = $items[9];
$row->alert_flag = $items[10];
$row->print_number = $items[11];
$row->keep_alive = $items[12];
if (!$row->save()) {
$type = 0;
$msg = '行:record型が一致しません。';
break;
}
} else {
$type = 0;
$msg = '行:record列数が一致しません。';
break;
}
}
} catch (\Exception $e) {
$msg = '行:record型が一致しません。';
$type = 0;
}
if ($type) {
DB::commit();
return redirect()->route('parks')->with('success', __('輸入成功'));
} else {
DB::rollBack();
return redirect()->route('parks')->with('error', __($msg, ['record' => $record]));
}
} else {
return redirect()->route('parks')->with('error', __('あなたはcsvファイルを選択していません。'));
}
}
public function checkDuplicate(\Illuminate\Http\Request $request)
{
$parkName = $request->input('park_name');
$duplicate = Park::where('park_name', $parkName)->first();
if ($duplicate) {
return response()->json([
'duplicate' => true,
'park_id' => $duplicate->park_id,
'park_name' => $duplicate->park_name,
]);
}
return response()->json(['duplicate' => false]);
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class PeriodicalController extends Controller
{
// 画面
public function list(Request $request)
{
// Bladeで使うカラム名id, nameで取得
$parks = DB::table('park')
->select('park_id', 'park_name')
->orderBy('park_name')
->get();
// 必要なら選択中のpark_idも渡す
$selectedParkId = $request->input('park_id', '');
return view('admin.periodical.list', compact('parks', 'selectedParkId'));
}
// 画面上の3つの統計用データ
public function listData(Request $request)
{
$parkId = $request->input('park_id');
// 契約状況
$bicycleGeneral = DB::table('regular_contract')
->where('park_id', $parkId)
->where('user_categoryid', 1)
->where('ptype_id', 1) // 1:自転車
->where('contract_cancel_flag', 0)
->count();
$bicycleStudent = DB::table('regular_contract')
->where('park_id', $parkId)
->where('user_categoryid', 2)
->where('ptype_id', 1)
->where('contract_cancel_flag', 0)
->count();
// 原付・その他も同様に集計
$contractSummary = [
[
'type' => '自転車',
'general_count' => $bicycleGeneral,
'general_extra' => '',
'student_count' => $bicycleStudent,
'student_extra' => '',
'use_total' => $bicycleGeneral + $bicycleStudent,
'vacancy' => 8, // 例: 空き数
'total' => $bicycleGeneral + $bicycleStudent + 8,
'last' => [
'reserve_date' => '2025/07/27',
'contract_date' => '',
],
],
// 原付・その他も同様に
];
// 空き待ち状況
$waitingSummary = [
[
'type' => '自転車',
'general_count' => 28,
'general_head' => '2023/03/08',
'student_count' => 6,
'student_head' => '2023/11/04',
'total' => 34,
],
// 原付・その他も同様に
];
// 更新状況
$renewalSummary = [];
for ($m = 1; $m <= 12; $m++) {
$renewalSummary[] = [
'month' => sprintf('%02d月', $m),
'bicycle_general' => 0,
'bicycle_student' => 0,
'bicycle_total' => 0,
'moped_general' => 0,
'moped_student' => 0,
'moped_total' => 0,
'others_general' => 0,
'others_student' => 0,
'others_total' => 0,
];
}
return response()->json([
'contract_summary' => $contractSummary,
'waiting_summary' => $waitingSummary,
'renewal_summary' => $renewalSummary,
]);
}
}

View File

@ -0,0 +1,175 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Pplace;
use App\Models\Ope;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Response;
class PplaceController extends Controller
{
public function list(Request $request)
{
$inputs = [
'isExport' => 0,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
];
$inputs['list'] = Pplace::search($inputs);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
return redirect()->route('pplace');
}
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'),
];
$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('pplace')->with('success', '登録成功');
} else {
$inputs['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
return view('admin.Pplace.add', $inputs);
}
public function edit(Request $request, $id, $view = '')
{
$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('pplace')->with('success', '更新成功');
} else {
$data['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
return view($view ?: 'admin.Pplace.edit', $data);
}
public function info(Request $request, $id)
{
return $this->edit($request, $id, 'admin.Pplace.info');
}
public function delete(Request $request)
{
$pk = $request->get('pk');
if ($pk && Pplace::destroy($pk)) {
return redirect()->route('pplace')->with('success', '削除成功');
}
return redirect()->route('pplace')->with('error', '削除失敗');
}
public function export()
{
$headers = [
"Content-type" => "text/csv;charset=UTF-8",
"Content-Disposition" => "attachment; filename=Pplace.csv",
];
$data = Pplace::all();
$columns = ['ID', '番号', '備考', 'オペレータID'];
$filename = "Pplace.csv";
$file = fopen($filename, 'w+');
fputcsv($file, $columns);
foreach ($data as $item) {
fputcsv($file, [
$item->pplace_id,
$item->pplace_number,
$item->pplace_remarks,
$item->operator_id,
]);
}
fclose($file);
return Response::download($filename, $filename, $headers);
}
public function import(Request $request)
{
$file = $request->file('file');
if (!$file) {
return redirect()->route('pplace')->with('error', 'CSVファイルを選択してください');
}
$data = \App\Utils::csvToArray($file);
$record = 0;
DB::beginTransaction();
try {
foreach ($data as $key => $row) {
$record = $key + 2;
if (count($row) < 3) throw new \Exception('列数が不正です');
Pplace::create([
'pplace_number' => $row[0],
'pplace_remarks' => $row[1],
'operator_id' => $row[2],
]);
}
DB::commit();
return redirect()->route('pplace')->with('success', 'インポート成功');
} catch (\Exception $e) {
DB::rollBack();
return redirect()->route('pplace')->with('error', "{$record} : " . $e->getMessage());
}
}
private function __buildErrorMessasges($validator)
{
return implode("\n", $validator->errors()->all());
}
}

View File

@ -0,0 +1,259 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\PriceRequest;
use App\Models\Park;
use App\Models\Price;
use App\Models\Psection;
use App\Models\Ptype;
use App\Models\Usertype;
use App\Models\Utils;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Response;
class PriceController extends Controller
{
public function list(Request $request)
{
$inputs = [
'isExport' => 0,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
];
$inputs['list'] = Price::search($inputs);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
return redirect()->route('prices');
}
return view('admin.prices.list', $inputs);
}
public function add(Request $request)
{
$inputs = [
'prine_name' => $request->input('prine_name'), // 商品名
'price_month' => $request->input('price_month',''), // 期間
'park_id' => $request->input('park_name'), // 駐輪場
'psection_id' => $request->input('psection_subject'), // 車種区分
'price_ptypeid' => $request->input('ptype_subject'), // 駐輪分類
'user_categoryid' => $request->input('user_category_name'), // 利用者分類
'pplace_id' => $request->input('pplace_id'), // 駐車車室
'price' => $request->input('price'), // 駐輪料金(税込)
];
$dataList = $this->getDataDropList();
$inputs = array_merge($inputs, $dataList);
if ($request->isMethod('POST')) {
$type = false;
$validation = new PriceRequest();
$rules = $validation->rules();
$validator = Validator::make($request->all(), $rules, $validation->messages());
if (!$validator->fails()) {
\DB::transaction(function () use ($inputs, &$type) {
$new = new Price();
$new->fill($inputs);
if( $new->save()){
$type = true;
}
});
if ($type) {
$request->session()->flash('success', __('新しい成功を創造する。'));
return redirect()->route('prices');
} else {
$request->session()->flash('error', __('新しい作成に失敗しました'));
}
}else {
$inputs['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
return view('admin.prices.add', $inputs);
}
public function edit(Request $request, $pk ,$view=''){
$price = Price::getByPk($pk);
if (empty($pk) || empty($price)) {
abort('404');
}
$data = $price->getAttributes();
$dataList = $this->getDataDropList();
$data = array_merge($data, $dataList);
if ($request->isMethod('POST')) {
$type = false;
$validation = new PriceRequest();
$rules = $validation->rules();
$validator = Validator::make($request->all(), $rules, $validation->messages());
$requestAll = $request->all();
$requestAll['price_ptypeid]'] = $request->input('ptype_subject');
$requestAll['user_categoryid'] = $request->input('user_category_name'); // 利用者分類
$requestAll['psection_id'] = $request->input('psection_subject');
$requestAll['park_id'] = $request->input('park_name');
$data = array_merge($data, $requestAll);
if (!$validator->fails()) {
\DB::transaction(function () use ($data, &$type,$price) {
$price->fill($data);
$price->save();
$type = true;
});
if ($type) {
$request->session()->flash('success', __('更新に成功しました'));
return redirect()->route('prices');
} else {
$request->session()->flash('error', __('更新に失敗しました'));
}
}else {
$data['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
if ($view != '') {
return view($view, $data);
}
return view('admin.prices.edit', $data);
}
public function delete(Request $request)
{
$arr_pk = $request->get('pk');
if ($arr_pk) {
if (Price::deleteByPk($arr_pk)) {
return redirect()->route('prices')->with('success', __("削除成功。"));
} else {
return redirect()->route('prices')->with('error', __('削除に失敗しました。'));
}
}
return redirect()->route('prices')->with('error', __('削除するユーザーを選択してください。'));
}
public function export(Request $request)
{
$headers = array(
"Content-type" => "text/csv;charset=UTF-8",
'Content-Encoding: UTF-8',
"Content-Disposition" => "attachment; filename=file.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
];
$dataExport = Price::search($inputs);
$columns = array(
__('駐車場所ID'),// 0
__('商品名'),// 1
__('期間'),// 2
__('駐輪場ID'),// 3
__('駐輪場名'),// 3
__('車種区分ID'),// 5
__('車種区分'),// 6
__('駐輪分類ID'),// 7
__('駐輪分類'),// 8
__('利用者分類ID'),// 9
__('利用者分類'),// 10
__('駐車車室ID'),//11
__('駐輪料金(税込)'),// 12
);
$filename = "駐輪場所、料金マスタ.csv";
$file = fopen($filename, 'w+');
fputcsv($file, $columns);
foreach ($dataExport as $items) {
fputcsv($file, array(
$items->price_parkplaceid,// 0
$items->prine_name, // 1
$items->price_month, // 2
$items->park_id, // 3
!empty($items->getPark())? $items->getPark()->park_name:'' ,// 4
$items->psection_id, // 5
!empty($items->getPSection())? $items->getPSection()->psection_subject:'',// 6
$items->price_ptypeid, // 7
!empty($items->getPType())? $items->getPType()->ptype_subject:'' ,// 8
$items->user_categoryid, //9
!empty($items->getUserType())? $items->getUserType()->print_name:'' ,//10
$items->pplace_id,// 11
$items->price, // 12
));
}
fclose($file);
return Response::download($filename, $filename, $headers);
}
public function import(Request $request)
{
$file = $request->file('file');
if(!empty($file)){
$data = Utils::csvToArray($file);
$type = 1;
$msg = '';
$record = 0;
DB::beginTransaction();
try {
Price::query()->delete();
$col = 13;
foreach ($data as $key => $items) {
$record = $key + 2;
if (count($items) == $col) {
$row = new Price();
$row->price_parkplaceid = $items[0];
$row->prine_name = $items[1];
$row->price_month = $items[2];
$row->park_id = $items[3];
$row->psection_id = $items[5];
$row->price_ptypeid = $items[7];
$row->user_categoryid = $items[9];
$row->pplace_id = $items[11];
$row->price = $items[12];
if (!$row->save()) {
$type = 0;
$msg = '行:record型が一致しません。';
break;
}
} else {
$type = 0;
$msg = '行:record列数が一致しません。';
break;
}
}
} catch (\Exception $e) {
$msg = '行:record型が一致しません。';
$type = 0;
}
if ($type) {
DB::commit();
return redirect()->route('prices')->with('success', __('輸入成功'));
} else {
DB::rollBack();
return redirect()->route('prices')->with('error', __($msg, ['record' => $record]));
}
} else {
return redirect()->route('prices')->with('error', __('あなたはcsvファイルを選択していません。'));
}
}
public function info(Request $request, $id)
{
return $this->edit($request, $id, 'admin.prices.info');
}
public function getDataDropList()
{
$data['parks'] = Park::getList() ;
$data['psections'] = Psection::getList() ;
$data['ptypes'] = Ptype::getList() ;
$data['userTypes'] = Usertype::getList() ;
return $data;
}
}

View File

@ -0,0 +1,144 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Park;
use App\Models\PriceA;
use App\Models\PriceB;
class PriceListController extends Controller
{
/**
* 料金一覧表 一覧ページ
*/
public function list(Request $request)
{
$parkList = Park::orderBy('park_name')->get();
$parkId = $request->input('park_id', '');
$masterList = [
[
'name' => 'マスターA',
'status' => '利用中',
'groups' => [],
],
[
'name' => 'マスターB',
'status' => '待作中',
'groups' => [],
],
];
if ($parkId) {
// parkとprice_aをJOIN
$aRows = \DB::table('price_a')
->join('park', 'park.park_id', '=', 'price_a.park_id')
->where('price_a.park_id', $parkId)
->select('price_a.*') // 必要ならpark.*も
->get();
$aGrouped = $this->groupPriceRows($aRows);
$masterList[0]['groups'] = $aGrouped;
// マスターBも同様に取得・整形する場合はここに追加
}
return view('admin.PriceList.list', [
'parkList' => $parkList,
'parkId' => $parkId,
'masterList' => $masterList,
]);
}
/**
* 料金データを「駐輪分類ID-ユーザ分類ID-駐輪場ID」でグループ化
*/
private function groupPriceRows($rows)
{
$result = [];
foreach ($rows as $row) {
// グループキーは分類ID+ユーザ分類ID+駐輪場ID
$key = $row->price_ptypeid . '-' . $row->user_categoryid . '-' . $row->park_id;
if (!isset($result[$key])) {
$result[$key] = [
'id' => $row->price_parkplaceid,
'classification' => $row->price_ptypeid,
'room_number' => '', // 必要ならpplace_id等をセット
'category1' => $row->prine_name ?? '',
'category2' => '',
'category3' => '',
'bike_1m' => '',
'bike_2m' => '',
'bike_3m' => '',
'bike_6m' => '',
'bike_12m' => '',
// 必要なら原付・自動二輪も同様に追加
];
}
// 月数ごとに金額をセット
if ($row->price_month == 1) {
$result[$key]['bike_1m'] = $row->price;
} elseif ($row->price_month == 2) {
$result[$key]['bike_2m'] = $row->price;
} elseif ($row->price_month == 3) {
$result[$key]['bike_3m'] = $row->price;
} elseif ($row->price_month == 6) {
$result[$key]['bike_6m'] = $row->price;
} elseif ($row->price_month == 12) {
$result[$key]['bike_12m'] = $row->price;
}
}
return array_values($result);
}
public function update(Request $request)
{
foreach ($request->input('rows', []) as $row) {
$id = $row['id'] ?? null;
if (!$id) continue;
// 更新対象の月リスト
$months = [
'bike_1m' => 1,
'bike_2m' => 2,
'bike_3m' => 3,
'bike_6m' => 6,
'bike_12m' => 12,
];
foreach ($months as $field => $month) {
if (isset($row[$field])) {
// price_aから該当レコードを取得
$item = \App\Models\PriceA::where('price_parkplaceid', $id)
->where('price_month', $month)
->first();
if ($item) {
$item->price = $row[$field];
$item->save();
}
}
}
// 原付・自動二輪も同様に必要なら追加
}
return back()->with('success', '金額を更新しました');
}
public function insert(Request $request)
{
// 例bike_2m2ヶ月だけ新規追加する場合
if ($request->filled('bike_2m')) {
$row = new \App\Models\PriceA();
$row->park_id = $request->input('park_id'); // 必要に応じて
$row->price = $request->input('bike_2m');
$row->price_month = 2;
// 他の必要なカラムもセット
$row->save();
}
// 他の月も同様に必要なら追加
return back()->with('success', '金額を追加しました');
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Psection;
class PsectionController extends Controller
{
// 一覧画面
public function list(Request $request)
{
// ソート順
$sort = $request->input('sort', 'psection_id');
$sort_type = $request->input('sort_type', 'asc');
$query = Psection::query();
if (in_array($sort, ['psection_id', 'psection_subject'])) {
$query->orderBy($sort, $sort_type);
}
$list = $query->get();
return view('admin.psection.list', compact('list', 'sort', 'sort_type'));
}
// 新規追加
public function add(Request $request)
{
if ($request->isMethod('post')) {
$validated = $request->validate([
'psection_id' => 'required|integer|unique:psection,psection_id',
'psection_subject' => 'required|string|max:255',
]);
Psection::create($validated);
return redirect()->route('psection')->with('success', '車種区分を追加しました');
}
return view('admin.psection.add');
}
// 編集
public function edit(Request $request, $id)
{
$psection = Psection::findOrFail($id);
if ($request->isMethod('post')) {
$validated = $request->validate([
'psection_subject' => 'required|string|max:255',
]);
$psection->update($validated);
return redirect()->route('psection')->with('success', '車種区分を更新しました');
}
return view('admin.psection.edit', compact('psection'));
}
// 詳細(info)
public function info(Request $request, $id)
{
$psection = Psection::findOrFail($id);
return view('admin.psection.info', compact('psection'));
}
// 削除
public function delete(Request $request)
{
$ids = $request->input('pk', []);
if (!empty($ids)) {
Psection::whereIn('psection_id', $ids)->delete();
return redirect()->route('psection')->with('success', '削除しました');
}
return redirect()->route('psection')->with('error', '削除対象を選択してください');
}
}

View File

@ -0,0 +1,230 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Ptype;
use App\Utils;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Response;
class PtypeController extends Controller
{
public function list(Request $request)
{
$inputs = [
'isMethodPost' => 0,
'isExport' => 0,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
];
$inputs['isMethodPost'] = $request->isMethod('post');
$inputs['list'] = Ptype::search($inputs);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
return redirect()->route('ptypes');
}
return view('admin.ptypes.list', $inputs);
}
public function add(Request $request)
{
$inputs = [
//TODO 駐輪分類ID not found in database specs
'ptype_subject' => $request->input('ptype_subject'), // 駐輪分類名
'ptype_remarks' => $request->input('ptype_remarks'), // 備考
];
if ($request->isMethod('POST')) {
$rules = [
'ptype_subject' => 'required|string|max:255',
'ptype_sort' => 'nullable|integer',
'ptype_remarks' => 'nullable|string|max:255',
];
$messages = [
'ptype_subject.required' => '駐輪分類名は必須です。',
];
$validator = Validator::make($request->all(), $rules, $messages);
if (!$validator->fails()) {
\DB::transaction(function () use ($inputs, &$type) {
$new = new Ptype();
$new->fill($inputs);
if ($new->save()) {
$type = true;
}
});
if ($type) {
$request->session()->flash('success', __('データ新規作成しました。'));
return redirect()->route('ptypes');
} else {
$request->session()->flash('error', __('新規作成に失敗しました'));
}
} else {
$inputs['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
return view('admin.ptypes.add', $inputs);
}
public function edit(Request $request, $pk, $view = '')
{
$ptype = Ptype::getByPk($pk);
if (empty($pk) || empty($ptype)) {
abort('404');
}
$data = $ptype->getAttributes();
$dataList = $this->getDataDropList();
$data = array_merge($data, $dataList);
if ($request->isMethod('POST')) {
$type = false;
// ここを修正
$rules = [
'ptype_subject' => 'required|string|max:255',
'ptype_sort' => 'nullable|integer',
'ptype_remarks' => 'nullable|string|max:255',
];
$messages = [
'ptype_subject.required' => '駐輪分類名は必須です。',
];
$validator = Validator::make($request->all(), $rules, $messages);
$requestAll = $request->all();
$data = array_merge($data, $requestAll);
if (!$validator->fails()) {
\DB::transaction(function () use ($data, &$type, $ptype) {
$ptype->fill($data);
$ptype->save();
$type = true;
});
if ($type) {
$request->session()->flash('success', __('更新に成功しました'));
return redirect()->route('ptypes');
} else {
$request->session()->flash('error', __('更新に失敗しました'));
}
} else {
$data['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
if ($view != '') {
return view($view, $data);
}
return view('admin.ptypes.edit', $data);
}
public function delete(Request $request)
{
$arr_pk = $request->get('pk');
if ($arr_pk) {
if (Ptype::deleteByPk($arr_pk)) {
return redirect()->route('ptypes')->with('success', __("削除が完了しました。"));
} else {
return redirect()->route('ptypes')->with('error', __('削除に失敗しました。'));
}
}
return redirect()->route('ptypes')->with('error', __('削除するデータを選択してください。'));
}
public function info(Request $request, $id)
{
return $this->edit($request, $id, 'admin.ptypes.info');
}
public function getDataDropList()
{
$data = [];
return $data;
}
public function export(Request $request)
{
$headers = array(
"Content-type" => "text/csv;charset=UTF-8",
'Content-Encoding: UTF-8',
"Content-Disposition" => "attachment; filename=file.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
];
$dataExport = Ptype::search($inputs);
$columns = array(
__('駐輪分類ID'),
__('駐輪分類名'),
__('備考'),
);
$filename = "駐輪分類マスタ.csv";
$file = fopen($filename, 'w+');
fputcsv($file, $columns);
foreach ($dataExport as $items) {
fputcsv($file, array(
$items->ptype_id,
$items->ptype_subject,
$items->ptype_remarks,
));
}
fclose($file);
return Response::download($filename, $filename, $headers);
}
public function import(Request $request)
{
$file = $request->file('file');
if (!empty($file)) {
$data = Utils::csvToArray($file);
$type = 1;
$msg = '';
$record = 0;
DB::beginTransaction();
try {
Ptype::query()->delete();
$col = 3;
foreach ($data as $key => $items) {
$record = $key + 2;
if (count($items) == $col) {
$row = new Ptype();
$row->ptype_id = $items[0];
$row->ptype_subject = $items[1];
$row->ptype_remarks = $items[2];
if (!$row->save()) {
$type = 0;
$msg = '行:record型が一致しません。';
break;
}
} else {
$type = 0;
$msg = '行:record列数が一致しません。';
break;
}
}
} catch (\Exception $e) {
dd($e);
$msg = '行:record型が一致しません。';
$type = 0;
}
if ($type) {
DB::commit();
return redirect()->route('ptypes')->with('success', __('輸入成功'));
} else {
DB::rollBack();
return redirect()->route('ptypes')->with('error', __($msg, ['record' => $record]));
}
} else {
return redirect()->route('ptypes')->with('error', __('あなたはcsvファイルを選択していません。'));
}
}
}

View File

@ -0,0 +1,528 @@
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class RegularContractController
{
/**
* 定期契約一覧
* - ベース表: regular_contractrc
* - 付加情報: useru, usertypet, parkp
* - 画面変数: $list, $sort, $sort_type既存に合わせる
*/
public function list(Request $request)
{
// ===== ソート(既定: contract_id DESC=====
$sort = $request->input('sort', 'contract_id');
$sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc';
// ===== 絞り込み(テキスト系)=====
// フォームの name 属性と完全一致させる&既定値は空文字にして Blade が未定義にならないようにする
$contract_qr_id = trim((string) $request->input('contract_qr_id', ''));
$user_id = trim((string) $request->input('user_id', ''));
$park_id = trim((string) $request->input('park_id', ''));
$user_phonetic = trim((string) $request->input('user_phonetic', '')); // フリガナ
$phone = trim((string) $request->input('phone', '')); // 電話(携帯/自宅)
$email = trim((string) $request->input('email', '')); // メール
$usertype_name_kw = trim((string) $request->input('usertype_name', '')); // 利用者分類名
$park_name_kw = trim((string) $request->input('park_name', '')); // 駐輪場名
// ===== 絞り込み(日付範囲)=====
$reserve_from = $request->input('reserve_date_from', '');
$reserve_to = $request->input('reserve_date_to', '');
$created_from = $request->input('contract_created_from', '');
$created_to = $request->input('contract_created_to', '');
$updated_from = $request->input('contract_updated_from', '');
$updated_to = $request->input('contract_updated_to', '');
$canceled_from = $request->input('contract_canceled_from', '');
$canceled_to = $request->input('contract_canceled_to', '');
// ===== 列挙(全て/0/1=====
$contract_flag = $request->input('contract_flag', '');
$contract_permission = $request->input('contract_permission', '');
$tag_qr_flag = $request->input('tag_qr_flag', '');
$update_flag = $request->input('update_flag', '');
$contract_cancel_flag = $request->input('contract_cancel_flag', '');
// ===== クエリ(結合込み)=====
$q = DB::table('regular_contract as rc')
->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id')
->leftJoin('usertype as t', 't.user_categoryid', '=', 'rc.user_categoryid')
->leftJoin('park as p', 'p.park_id', '=', 'rc.park_id')
->select([
// rc
'rc.contract_id',
'rc.contract_qr_id',
'rc.user_id',
'rc.user_categoryid',
'rc.reserve_id',
'rc.park_id',
'rc.price_parkplaceid',
'rc.user_securitynum',
'rc.reserve_date',
'rc.contract_reserve',
'rc.contract_created_at',
'rc.contract_updated_at',
'rc.contract_cancelday',
'rc.contract_flag',
'rc.contract_permission',
'rc.contract_cancel_flag',
'rc.tag_qr_flag',
'rc.update_flag',
'rc.park_position',
'rc.ope_id',
// user
'u.user_name',
'u.user_phonetic',
'u.user_mobile',
'u.user_homephone',
'u.user_primemail',
// usertype & park
DB::raw('t.print_name as usertype_name'),
DB::raw('p.park_name as park_name'),
]);
// ===== LIKE / キーワード =====
if ($contract_qr_id !== '') {
$q->where('rc.contract_qr_id', 'like', "%{$contract_qr_id}%");
}
if ($user_id !== '') {
$q->where('rc.user_id', 'like', "%{$user_id}%");
}
if ($park_id !== '') {
$q->where('rc.park_id', 'like', "%{$park_id}%");
}
if ($user_phonetic !== '') {
$q->where('u.user_phonetic', 'like', "%{$user_phonetic}%");
}
if ($email !== '') {
$q->where('u.user_primemail', 'like', "%{$email}%");
}
if ($usertype_name_kw !== '') {
$q->where('t.print_name', 'like', "%{$usertype_name_kw}%");
}
if ($park_name_kw !== '') {
$q->where('p.park_name', 'like', "%{$park_name_kw}%");
}
if ($phone !== '') {
$q->where(function ($w) use ($phone) {
$w->where('u.user_mobile', 'like', "%{$phone}%")
->orWhere('u.user_homephone', 'like', "%{$phone}%");
});
}
// ===== 日付範囲 =====
if ($reserve_from) {
$q->whereDate('rc.reserve_date', '>=', $reserve_from);
}
if ($reserve_to) {
$q->whereDate('rc.reserve_date', '<=', $reserve_to);
}
if ($created_from) {
$q->whereDate('rc.contract_created_at', '>=', $created_from);
}
if ($created_to) {
$q->whereDate('rc.contract_created_at', '<=', $created_to);
}
if ($updated_from) {
$q->whereDate('rc.contract_updated_at', '>=', $updated_from);
}
if ($updated_to) {
$q->whereDate('rc.contract_updated_at', '<=', $updated_to);
}
if ($canceled_from) {
$q->whereDate('rc.contract_cancelday', '>=', $canceled_from);
}
if ($canceled_to) {
$q->whereDate('rc.contract_cancelday', '<=', $canceled_to);
}
// ===== 列挙フィルタ =====
if ($contract_flag !== '') {
$q->where('rc.contract_flag', (int) $contract_flag);
}
if ($contract_permission !== '') {
$q->where('rc.contract_permission', (int) $contract_permission);
}
if ($tag_qr_flag !== '') {
$q->where('rc.tag_qr_flag', (int) $tag_qr_flag);
}
if ($update_flag !== '') {
$q->where('rc.update_flag', (int) $update_flag);
}
if ($contract_cancel_flag !== '') {
$q->where('rc.contract_cancel_flag', (int) $contract_cancel_flag);
}
// ===== ソート(仮想列は結合側にマッピング)=====
$sortable = [
'contract_id',
'contract_qr_id',
'user_id',
'user_categoryid',
'reserve_id',
'park_id',
'price_parkplaceid',
'user_securitynum',
'reserve_date',
'contract_reserve',
'contract_created_at',
'contract_updated_at',
'contract_cancelday',
'contract_flag',
'contract_permission',
'contract_cancel_flag',
'tag_qr_flag',
'update_flag',
'park_position',
'ope_id',
// 結合先の見出し列
'user_name',
'user_phonetic',
'user_mobile',
'user_homephone',
'user_primemail',
'usertype_name',
'park_name',
];
if (!in_array($sort, $sortable, true)) {
$sort = 'contract_id';
}
$sortMap = [
'user_name' => 'u.user_name',
'user_phonetic' => 'u.user_phonetic',
'user_mobile' => 'u.user_mobile',
'user_homephone' => 'u.user_homephone',
'user_primemail' => 'u.user_primemail',
'usertype_name' => 't.print_name',
'park_name' => 'p.park_name',
];
$sortColumn = $sortMap[$sort] ?? ('rc.' . $sort);
$list = $q->orderBy($sortColumn, $sortType)->paginate(50);
// ===== 画面へBlade 側が参照するすべての変数を渡す)=====
return view('admin.regularcontracts.list', [
'list' => $list,
'sort' => $sort,
'sort_type' => $sortType,
// 入力保持(テキスト)
'contract_qr_id' => $contract_qr_id,
'user_id' => $user_id,
'park_id' => $park_id,
'user_phonetic' => $user_phonetic,
'phone' => $phone,
'email' => $email,
'usertype_name' => $usertype_name_kw,
'park_name' => $park_name_kw,
// 入力保持(日付)
'reserve_date_from' => $reserve_from,
'reserve_date_to' => $reserve_to,
'contract_created_from' => $created_from,
'contract_created_to' => $created_to,
'contract_updated_from' => $updated_from,
'contract_updated_to' => $updated_to,
'contract_canceled_from' => $canceled_from,
'contract_canceled_to' => $canceled_to,
// 入力保持(列挙)
'contract_flag' => $contract_flag,
'contract_permission' => $contract_permission,
'tag_qr_flag' => $tag_qr_flag,
'update_flag' => $update_flag,
'contract_cancel_flag' => $contract_cancel_flag,
]);
}
/**
* 定期契約編集GET: 画面表示 / POST: 更新実行)
* - 主キー: contract_id
*/
public function edit(Request $request, $id)
{
$id = (int) $id;
if ($request->isMethod('get')) {
$row = DB::table('regular_contract')->where('contract_id', $id)->first();
if (!$row) {
abort(404);
}
return view('admin.regularcontracts.edit', [
'row' => $row,
'contract_id' => $id,
]);
}
$v = Validator::make($request->all(), [
'user_id' => ['required', 'integer'],
'park_id' => ['required', 'integer'],
// 任意項目
'contract_qr_id' => ['nullable', 'string', 'max:255'],
'user_categoryid' => ['nullable', 'integer'],
'reserve_id' => ['nullable', 'integer'],
'price_parkplaceid' => ['nullable', 'integer'],
'user_securitynum' => ['nullable', 'string', 'max:255'],
'reserve_date' => ['nullable', 'date'],
'contract_reserve' => ['nullable', 'string', 'max:255'],
'contract_created_at' => ['nullable', 'date'],
'contract_updated_at' => ['nullable', 'date'],
'contract_cancelday' => ['nullable', 'date'],
'contract_flag' => ['nullable', 'integer'],
'contract_permission' => ['nullable', 'integer'],
'contract_cancel_flag' => ['nullable', 'integer'],
'tag_qr_flag' => ['nullable', 'integer'],
'park_position' => ['nullable', 'string', 'max:255'],
'ope_id' => ['nullable', 'integer'],
]);
if ($v->fails()) {
return back()->withErrors($v)->withInput();
}
$data = [
'contract_qr_id' => $request->input('contract_qr_id'),
'user_id' => (int) $request->input('user_id'),
'user_categoryid' => $request->input('user_categoryid'),
'reserve_id' => $request->input('reserve_id'),
'park_id' => (int) $request->input('park_id'),
'price_parkplaceid' => $request->input('price_parkplaceid'),
'user_securitynum' => $request->input('user_securitynum'),
'reserve_date' => $request->input('reserve_date'),
'contract_reserve' => $request->input('contract_reserve'),
'contract_created_at' => $request->input('contract_created_at'),
'contract_updated_at' => $request->input('contract_updated_at'),
'contract_cancelday' => $request->input('contract_cancelday'),
'contract_flag' => $request->input('contract_flag'),
'contract_permission' => $request->input('contract_permission'),
'contract_cancel_flag' => $request->input('contract_cancel_flag'),
'tag_qr_flag' => $request->input('tag_qr_flag'),
'park_position' => $request->input('park_position'),
'ope_id' => $request->input('ope_id'),
'updated_at' => now(),
];
DB::table('regular_contract')->where('contract_id', $id)->update($data);
return redirect()->route('regularcontracts')->with('success', '定期契約を更新しました。');
}
/**
* 定期契約削除
* - 物理削除(必要なら cancel フラグ運用に切替)
*/
public function delete(Request $request)
{
$id = (int) $request->input('id');
DB::table('regular_contract')->where('contract_id', $id)->delete();
// 例:論理削除運用にする場合(必要なら運用側で切替)
// DB::table('regular_contract')->where('contract_id', $id)->update([
// 'contract_cancel_flag' => 1,
// 'contract_cancelday' => now(),
// 'updated_at' => now(),
// ]);
return redirect()->route('regularcontracts')->with('success', '定期契約を削除しました。');
}
/**
* 定期契約インポート(仮実装)
*/
public function import(Request $request)
{
if ($request->isMethod('get')) {
// GET で来たら一覧へ
return redirect()->route('regularcontracts');
}
// ファイル必須 & 形式チェック
$request->validate([
'file' => ['required', 'file', 'mimetypes:text/plain,text/csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'],
], [], [
'file' => 'インポートファイル',
]);
$file = $request->file('file');
// TODO: ここで実際のインポート処理CSV/XLSXの解析とレコード登録を書く
// 例Storage::putFile('imports', $file); で一旦保存してバッチに回す etc.
return redirect()->route('regularcontracts')->with('success', 'インポートを受け付けました。');
}
/**
* 定期契約エクスポート(仮実装)
* - 現時点では何もしません。ルーティング確認用のプレーンテキストを返します。
* - 後で CSV / Excel 出力処理に置き換えてください。
*/
public function export(Request $request)
{
// ── 出力タイプ(通常 / SMBC / 役所) ──────────────────────────────
$type = $request->query('type'); // null | smbc | city
// ── 出力ファイル名 ───────────────────────────────────────────────
$downloadName = '定期契約マスタ.csv';
if ($type === 'smbc')
$downloadName = '定期契約マスタ_SMBC.csv';
if ($type === 'city')
$downloadName = '定期契約マスタ_役所提出用.csv';
// ── 生成先storage/app/tmp 配下の一時ファイル) ─────────────────
$tmpDir = storage_path('app/tmp');
if (!is_dir($tmpDir)) {
@mkdir($tmpDir, 0755, true);
}
$tmpPath = $tmpDir . '/' . uniqid('regularcontracts_', true) . '.csv';
// ── CSV を作成Excel を考慮し UTF-8 BOM を付与) ───────────────
$fp = fopen($tmpPath, 'w+');
if ($fp === false) {
abort(500, 'CSV一時ファイルを作成できませんでした。');
}
// Excel 対策BOM
fwrite($fp, "\xEF\xBB\xBF");
// ヘッダー行(必要に応じて列を増減)
fputcsv($fp, ['定期契約ID', '利用者ID', '駐輪場ID', '契約日時']);
// ── データ取得(大量件数に備え chunk で分割取得) ────────────────
// ※ list() と同等の JOIN/SELECT を最低限に簡略化
DB::table('regular_contract as rc')
->leftJoin('user as u', 'u.user_id', '=', 'rc.user_id')
->orderBy('rc.contract_id', 'asc')
->select([
'rc.contract_qr_id',
'rc.user_id',
'rc.park_id',
'rc.contract_created_at',
])
->chunk(1000, function ($rows) use ($fp) {
foreach ($rows as $r) {
fputcsv($fp, [
$r->contract_qr_id,
$r->user_id,
$r->park_id,
$r->contract_created_at,
]);
}
});
fclose($fp);
// ── ダウンロードレスポンス(送信後に一時ファイル削除) ────────────
return response()->download(
$tmpPath,
$downloadName,
[
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $downloadName . '"',
'Pragma' => 'no-cache',
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Expires' => '0',
]
)->deleteFileAfterSend(true);
}
// 追加新規登録GET: 画面表示 / POST: 登録実行)
public function add(Request $request)
{
// 画面表示
if ($request->isMethod('get')) {
return view('admin.regularcontracts.add');
}
// ========= バリデーション =========
// ※ 必須最小限。その他は任意nullable
$v = Validator::make(
$request->all(),
[
'user_id' => ['required', 'integer'],
'park_id' => ['required', 'integer'],
'contract_qr_id' => ['nullable', 'string', 'max:255'],
'user_categoryid' => ['nullable', 'integer'],
'reserve_id' => ['nullable', 'integer'],
'price_parkplaceid' => ['nullable', 'integer'],
'reserve_date' => ['nullable', 'date'],
'contract_created_at' => ['nullable', 'date'],
'contract_cancelday' => ['nullable', 'date'],
'contract_permission' => ['nullable', 'integer'],
'contract_cancel_flag' => ['nullable', 'integer'],
'tag_qr_flag' => ['nullable', 'integer'],
'update_flag' => ['nullable', 'integer'],
'park_position' => ['nullable', 'string', 'max:255'],
'ope_id' => ['nullable', 'integer'],
// 画面の「定期有効月数」は DB の contract_valid_months に保存する
'enable_months' => ['nullable', 'integer', 'min:0'],
],
[],
[
'user_id' => '利用者ID',
'park_id' => '駐輪場ID',
'contract_qr_id' => '定期契約QRID',
'user_categoryid' => '利用者分類ID',
'reserve_id' => '定期予約ID',
'price_parkplaceid' => '駐輪場所ID',
'reserve_date' => '予約日時',
'contract_created_at' => '契約日時',
'contract_cancelday' => '解約日時',
'contract_permission' => 'シール発行許可',
'contract_cancel_flag' => '解約フラグ',
'tag_qr_flag' => 'タグ・QR',
'update_flag' => '(更新元)契約更新済フラグ',
'park_position' => '駐輪位置番号',
'ope_id' => 'オペレータID',
'enable_months' => '定期有効月数',
]
);
if ($v->fails()) {
return back()->withErrors($v)->withInput();
}
// ========= 登録データ作成 =========
// ここでは「regular_contract」テーブルに確実にある列を中心に保存します。
// 追加したい列があれば、同様にキーを増やして下さい。
$data = [
'contract_qr_id' => $request->input('contract_qr_id'),
'user_id' => (int) $request->input('user_id'),
'user_categoryid' => $request->input('user_categoryid'),
'reserve_id' => $request->input('reserve_id'),
'park_id' => (int) $request->input('park_id'),
'price_parkplaceid' => $request->input('price_parkplaceid'),
'reserve_date' => $request->input('reserve_date'),
'contract_created_at' => $request->input('contract_created_at') ?: now(), // 未指定なら現在時刻
'contract_cancelday' => $request->input('contract_cancelday'),
'contract_permission' => $request->input('contract_permission'),
'contract_cancel_flag' => $request->input('contract_cancel_flag'),
'tag_qr_flag' => $request->input('tag_qr_flag'),
'update_flag' => $request->input('update_flag'),
'park_position' => $request->input('park_position'),
'ope_id' => $request->input('ope_id'),
// 画面の enable_months → DB の contract_valid_months
'contract_valid_months' => $request->input('enable_months'),
'created_at' => now(),
'updated_at' => now(),
];
DB::table('regular_contract')->insert($data);
return redirect()
->route('regularcontracts')
->with('success', '定期契約を登録しました。');
}
}

View File

@ -0,0 +1,408 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\RegularContractRequest;
use App\Models\Park;
use App\Models\RegularContract;
use App\Models\User;
use App\Models\Usertype;
use App\Utils;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Response;
class RegularContractController extends Controller
{
public function list(Request $request)
{
$inputs = [
'isExport' => 0,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
];
$inputs['list'] = RegularContract::search($inputs);
//dd($inputs['list']->items());
// dd($inputs);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
return redirect()->route('regular_contracts');
}
return view('admin.regular_contracts.list', $inputs);
}
public function add(Request $request)
{
$inputs = [
'contract_qr_id' => $request->input('contract_qr_id'), // 定期契約QRID
'user_id' => $request->input('user_id'), // 利用者ID
'user_categoryid' => $request->input('user_categoryid'), // 利用者分類ID
'reserve_id' => $request->input('reserve_id'), // 定期予約ID
'park_id' => $request->input('park_id'), // 駐輪場ID
'price_parkplaceid' => $request->input('price_parkplaceid'), // 駐輪場所ID
'user_securitynum' => $request->input('user_securitynum'), // 防犯登録番号
'reserve_date' => $request->input('reserve_date'), // 予約日時
'contract_reserve' => $request->input('contract_reserve'), // 予約移行フラグ
'contract_created_at' => $request->input('contract_created_at'), // 契約日時
'contract_updated_at' => $request->input('contract_updated_at'), // 更新可能日
'contract_cancelday' => $request->input('contract_cancelday'), // 解約日時
'contract_reduction' => $request->input('contract_reduction'), // 減免措置
'contract_periods' => $request->input('contract_periods'), // 有効期間S
'contract_periode' => $request->input('contract_periode'), // 有効期間E
'contract_taxid' => $request->input('contract_taxid'), // 消費税ID
'billing_amount' => $request->input('billing_amount'), // 請求金額
'contract_payment_day' => $request->input('contract_payment_day'), // 授受日時
'contract_money' => $request->input('contract_money'), // 授受金額
'refunds' => $request->input('refunds'), // 解約時返戻金
'refunds_comment' => $request->input('refunds_comment'), // 返戻金付随情報
'repayment_at' => $request->input('repayment_at'), // 返金日
'contact_guid' => $request->input('contact_guid'), // 決済コード
'contact_shop_code' => $request->input('contact_shop_code'), // 店舗コード
'contract_cvs_class' => $request->input('contract_cvs_class'), // 授受種別
'contract_flag' => $request->input('contract_flag'), // 授受フラグ
'settlement_transaction_id' => $request->input('settlement_transaction_id'), // 決済トランザクションID
'contract_seal_issue' => $request->input('contract_seal_issue'), // シール発行数
'seal_reissue_request' => $request->input('seal_reissue_request'), // シール再発行リクエスト
'contract_permission' => $request->input('contract_permission'), // シール発行許可
'contract_cancel_flag' => $request->input('contract_cancel_flag'), // 解約フラグ
'tag_qr_flag' => $request->input('tag_qr_flag'), // タグ/QRフラグ
'tag_change_flag' => $request->input('tag_change_flag'), // オペレータータグ変更フラグ
'park_position' => $request->input('park_position'), // 駐輪位置番号
'ope_id' => $request->input('ope_id'), // オペレータID
'contract_manual' => $request->input('contract_manual'), // 手動通知
'contract_notice' => $request->input('contract_notice'), // 通知方法
'contract_payment_number' => $request->input('contract_payment_number'), // 受付番号
'created_at' => $request->input('created_at'),
'updated_at' => $request->input('updated_at'),
];
$dataList = $this->getDataDropList();
$inputs = array_merge($inputs, $dataList);
if ($request->isMethod('POST')) {
$type = false;
$validation = new RegularContractRequest();
$rules = $validation->rules();
if(!empty($inputs['billing_amount']) ){
$rules['billing_amount'] = 'numeric|between:0,999999999999.99';
}
if(!empty($inputs['contract_money']) ){
$rules['contract_money'] = 'numeric|between:0,999999999999.99';
}
if(!empty($inputs['user_aid']) ){
$rules['refunds'] ='numeric|between:0,999999999999.99';
}
if(!empty($inputs['settlement_transaction_id']) ){
$rules['settlement_transaction_id'] = 'integer';
}
if(!empty($inputs['contract_seal_issue']) ){
$rules['contract_seal_issue'] = 'integer';
}
if(!empty($inputs['ope_id']) ){
$rules['ope_id'] = 'integer';
}
$validator = Validator::make($request->all(), $rules, $validation->messages());
if (!$validator->fails()) {
\DB::transaction(function () use ($inputs, &$type) {
$new = new RegularContract();
$new->fill($inputs);
if ($new->save()) {
$type = true;
}
});
if ($type) {
$request->session()->flash('success', __('新しい成功を創造する。'));
return redirect()->route('regular_contracts');
} else {
$request->session()->flash('error', __('新しい作成に失敗しました'));
}
} else {
$inputs['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
return view('admin.regular_contracts.add', $inputs);
}
public function edit(Request $request, $contract_id, $view = '')
{
$regular_contract = RegularContract::getByPk($contract_id);
if (empty($contract_id) || empty($regular_contract)) {
abort('404');
}
$data = $regular_contract->getAttributes();
$dataList = $this->getDataDropList();
$data = array_merge($data, $dataList);
if ($request->isMethod('POST')) {
$type = false;
$inputs = $request->all();
$validation = new RegularContractRequest();
$rules = $validation->rules();
if(!empty($inputs['billing_amount']) ){
$rules['billing_amount'] = 'numeric|between:0,999999999999.99';
}
if(!empty($inputs['contract_money']) ){
$rules['contract_money'] = 'numeric|between:0,999999999999.99';
}
if(!empty($inputs['user_aid']) ){
$rules['refunds'] ='numeric|between:0,999999999999.99';
}
if(!empty($inputs['settlement_transaction_id']) ){
$rules['settlement_transaction_id'] = 'integer';
}
if(!empty($inputs['contract_seal_issue']) ){
$rules['contract_seal_issue'] = 'integer';
}
if(!empty($inputs['ope_id']) ){
$rules['ope_id'] = 'integer';
}
$validator = Validator::make($inputs, $rules, $validation->messages());
$data = array_merge($data, $inputs);
if (!$validator->fails()) {
\DB::transaction(function () use ($data, &$type, $regular_contract) {
$regular_contract->fill($data);
$regular_contract->save();
$type = true;
});
if ($type) {
$request->session()->flash('success', __('更新に成功しました'));
return redirect()->route('regular_contracts');
} else {
$request->session()->flash('error', __('更新に失敗しました'));
}
} else {
$data['errorMsg'] = $this->__buildErrorMessasges($validator);
}
}
if ($view != '') {
return view($view, $data);
}
return view('admin.regular_contracts.edit', $data);
}
public function delete(Request $request)
{
$arr_pk = $request->get('pk');
if ($arr_pk) {
if (RegularContract::deleteByPk($arr_pk)) {
return redirect()->route('regular_contracts')->with('success', __("削除が完了しました。"));
} else {
return redirect()->route('regular_contracts')->with('error', __('削除に失敗しました。'));
}
}
return redirect()->route('regular_contracts')->with('error', __('削除するユーザーを選択してください。'));
}
public function info(Request $request, $contract_id)
{
return $this->edit($request, $contract_id, 'admin.regular_contracts.info');
}
public function getDataDropList()
{
$data['users'] = User::getList();
$data['listUserType'] = Usertype::getList();
$data['park'] = Park::getList();
return $data;
}
public function export(Request $request)
{
$headers = array(
"Content-type" => "text/csv;charset=UTF-8",
'Content-Encoding: UTF-8',
"Content-Disposition" => "attachment; filename=file.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
];
$dataExport = RegularContract::search($inputs);
$columns = array(
__('定期契約ID'),
__('定期契約QRID'),// 1
__('利用者ID'),// 2
__('利用者分類ID'),// 3
__('定期予約ID'),// 4
__('駐輪場ID'),// 5
__('駐輪場所ID'),// 6
__('防犯登録番号'),// 7
__('予約日時'),// 8
__('予約移行フラグ'),// 9
__('契約日時'),// 10
__('更新可能日'),// 11
__('解約日時'),// 12
__('減免措置'),// 13
__('有効期間S'),// 14
__('有効期間E'),// 15
__('消費税ID'),// 16
__('請求金額'),// 17
__('授受日時'),// 18
__('授受金額'),// 19
__('解約時返戻金'),// 20
__('返戻金付随情報'),// 21
__('返金日'),// 22
__('決済コード'),// 23
__('店舗コード'),// 24
__('授受種別'),// 25
__('授受フラグ'),// 26
__('決済トランザクションID'),// 27
__('シール発行数'),// 28
__('シール再発行リクエスト'),// 29
__('シール発行許可'),// 30
__('解約フラグ'),// 31
__('タグ/QRフラグ'),// 32
__('オペレータータグ変更フラグ'),// 33
__('駐輪位置番号'),// 34
__('オペレータID'),// 35
__('手動通知'),// 36
__('通知方法'),// 37
__('受付番号'),// 38
);
$filename = "定期契約マスタ.csv";
$file = fopen($filename, 'w+');
fputcsv($file, $columns);
foreach ($dataExport as $items) {
fputcsv($file, array(
$items->contract_id, // 0
$items->contract_qr_id, // 1
$items->user_id, // 2
$items->user_categoryid, // 3
$items->reserve_id, // 4
$items->park_id, // 5
$items->price_parkplaceid, // 6
$items->user_securitynum, // 7
$items->reserve_date, // 8
$items->contract_reserve, // 9
$items->contract_created_at, // 10
$items->contract_updated_at, // 11
$items->contract_cancelday, // 12
$items->contract_reduction, // 13
$items->contract_periods, // 14
$items->contract_periode, // 15
$items->contract_taxid, // 16
$items->billing_amount, // 17
$items->contract_payment_day, // 18
$items->contract_money, // 19
$items->refunds, // 20
$items->refunds_comment, // 21
$items->repayment_at, // 22
$items->contact_guid, // 23
$items->contact_shop_code, // 24
$items->contract_cvs_class, // 25
$items->contract_flag, // 26
$items->settlement_transaction_id, // 27
$items->contract_seal_issue, // 28
$items->seal_reissue_request, // 29
$items->contract_permission, // 30
$items->contract_cancel_flag, // 31
$items->tag_qr_flag, // 32
$items->tag_change_flag, // 33
$items->park_position, // 34
$items->ope_id, // 35
$items->contract_manual, // 36
$items->contract_notice, // 37
$items->contract_payment_number, // 38
)
);
}
fclose($file);
return Response::download($filename, $filename, $headers);
}
public function import(Request $request)
{
$file = $request->file('file');
if (!empty($file)) {
$data = Utils::csvToArray($file);
$type = 1;
$msg = '';
$record = 0;
DB::beginTransaction();
try {
RegularContract::query()->delete();
$col = 39;
foreach ($data as $key => $items) {
$record = $key + 2;
if (count($items) == $col) {
$row = new RegularContract();
$row->contract_id = $items[0];
$row->contract_qr_id = $items[1];
$row->user_id = $items[2];
$row->user_categoryid = $items[3];
$row->reserve_id = $items[4];
$row->park_id = $items[5];
$row->price_parkplaceid = $items[6];
$row->user_securitynum = $items[7];
$row->reserve_date = $items[8];
$row->contract_reserve = $items[9];
$row->contract_created_at = $items[10];
$row->contract_updated_at = $items[11];
$row->contract_cancelday = $items[12];
$row->contract_reduction = $items[13];
$row->contract_periods = $items[14];
$row->contract_periode = $items[15];
$row->contract_taxid = $items[16];
$row->billing_amount = $items[17];
$row->contract_payment_day = $items[18];
$row->contract_money = $items[19];
$row->refunds = $items[20];
$row->refunds_comment = $items[21];
$row->repayment_at = $items[22];
$row->contact_guid = $items[23];
$row->contact_shop_code = $items[24];
$row->contract_cvs_class = $items[25];
$row->contract_flag = $items[26];
$row->settlement_transaction_id = $items[27];
$row->contract_seal_issue = $items[28];
$row->seal_reissue_request = $items[29];
$row->contract_permission = $items[30];
$row->contract_cancel_flag = $items[31];
$row->tag_qr_flag = $items[32];
$row->tag_change_flag = $items[33];
$row->park_position = $items[34];
$row->ope_id = $items[35];
$row->contract_manual = $items[36];
$row->contract_notice = $items[37];
$row->contract_payment_number = $items[38];
if (!$row->save()) {
$type = 0;
$msg = '行:record型が一致しません。';
break;
}
} else {
$type = 0;
$msg = '行:record列数が一致しません。';
break;
}
}
} catch (\Exception $e) {
dd($e);
$msg = '行:record型が一致しません。';
$type = 0;
}
if ($type) {
DB::commit();
return redirect()->route('regular_contracts')->with('success', __('輸入成功'));
} else {
DB::rollBack();
return redirect()->route('regular_contracts')->with('error', __($msg, ['record' => $record]));
}
} else {
return redirect()->route('regular_contracts')->with('error', __('あなたはcsvファイルを選択していません。'));
}
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ReservationController extends Controller
{
/**
* 予約者一覧表示
*/
public function list(Request $request)
{
$q = DB::table('reserve as r')
->select([
'r.user_id',
'u.user_name',
'u.user_phonetic',
'u.user_regident_zip',
'u.user_regident_pre',
'u.user_regident_city',
'u.user_regident_add',
'u.user_relate_zip',
'u.user_relate_pre',
'u.user_relate_city',
'u.user_relate_add',
'u.user_birthdate',
'u.user_gender',
'u.user_mobile',
'u.user_homephone',
'u.user_school',
'u.user_graduate',
'u.user_remarks',
'r.reserve_id',
'r.park_id',
'p.park_name',
'r.price_parkplaceid',
'r.psection_id',
'r.reserve_date',
'r.reserve_reduction as reduction',
'r.800m_flag as within_800m_flag',
])
->leftJoin('user as u', 'r.user_id', '=', 'u.user_id')
->leftJoin('park as p', 'r.park_id', '=', 'p.park_id'); // 追加
// フィルター条件
if ($request->filled('park_id')) {
$q->where('r.park_id', $request->input('park_id'));
}
if ($request->filled('user_id')) {
$q->where('r.user_id', $request->input('user_id'));
}
if ($request->filled('user_categoryid')) {
$q->where('r.user_categoryid', $request->input('user_categoryid'));
}
if ($request->filled('user_tag_serial')) {
$q->where('u.user_tag_serial', 'like', '%' . $request->input('user_tag_serial') . '%');
}
if ($request->filled('user_tag_serial_64')) {
$q->where('u.user_tag_serial_64', 'like', '%' . $request->input('user_tag_serial_64') . '%');
}
if ($request->filled('user_phonetic')) {
$q->where('u.user_phonetic', 'like', '%' . $request->input('user_phonetic') . '%');
}
if ($request->filled('user_mobile')) {
$q->where(function($sub) use ($request) {
$sub->where('u.user_mobile', 'like', '%' . $request->input('user_mobile') . '%')
->orWhere('u.user_homephone', 'like', '%' . $request->input('user_mobile') . '%');
});
}
if ($request->filled('user_primemail')) {
$q->where('u.user_primemail', 'like', '%' . $request->input('user_primemail') . '%');
}
if ($request->filled('user_workplace')) {
$q->where('u.user_workplace', 'like', '%' . $request->input('user_workplace') . '%');
}
if ($request->filled('user_school')) {
$q->where('u.user_school', 'like', '%' . $request->input('user_school') . '%');
}
// ソート
$sort = $request->input('sort', 'r.reserve_id');
$sortType = $request->input('sort_type', 'desc');
$allowSorts = ['r.reserve_id', 'r.reserve_date', 'r.reserve_start', 'r.reserve_end'];
if (!in_array($sort, $allowSorts)) {
$sort = 'r.reserve_id';
}
$sortType = ($sortType === 'asc') ? 'asc' : 'desc';
$rows = $q->orderBy($sort, $sortType)->paginate(20)->withQueryString();
// 駐輪場リスト取得(必要なら)
$parks = DB::table('park')->select('park_id', 'park_name')->get();
return view('admin.reservation.list', compact('rows', 'sort', 'sortType', 'parks'));
}
}

View File

@ -0,0 +1,309 @@
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Support\Facades\Schema;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
class ReservesController
{
/**
* 予約一覧
* - 基本表: reserver
* - 付加情報: useru, parkp
* - 画面変数: $list, $sort, $sort_type利用者マスタの書式に準拠
*
* reserve テーブルの主な列:
* reserve_id, contract_id, user_id, park_id, price_parkplaceid, psection_id,
* reserve_date, reserve_start, reserve_end, reserve_cancelday, valid_flag, ope_id など
* DDL dump の通り【turn12file6†L15-L37】
*/
public function list(Request $request)
{
// ── 並び順(既定: reserve_id DESC──────────────────────────────
$sort = $request->input('sort', 'reserve_id');
$sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc';
// ── 絞り込み(必要最低限:利用者/駐輪場/期間)──────────────────
$userId = trim((string) $request->input('user_id', ''));
$parkId = trim((string) $request->input('park_id', ''));
$fromDt = $request->input('reserve_date_from', '');
$toDt = $request->input('reserve_date_to', '');
$keyword = trim((string) $request->input('keyword', '')); // 利用者名かな など
// ── クエリ構築 ────────────────────────────────────────────────
$q = DB::table('reserve as r')
->leftJoin('user as u', 'u.user_id', '=', 'r.user_id') // user: user_name, user_phonetic 等【turn12file9†L26-L34】
->leftJoin('park as p', 'p.park_id', '=', 'r.park_id') // park: park_name 等【turn12file4†L17-L25】
->select([
'r.reserve_id',
'r.contract_id',
'r.user_id',
'r.park_id',
'r.price_parkplaceid',
'r.psection_id',
'r.reserve_date',
'r.reserve_start',
'r.reserve_end',
'r.reserve_cancelday',
'r.valid_flag',
'r.ope_id',
DB::raw('u.user_name as user_name'),
DB::raw('u.user_phonetic as user_phonetic'),
DB::raw('u.user_mobile as user_mobile'),
DB::raw('p.park_name as park_name'),
]);
if ($userId !== '')
$q->where('r.user_id', 'like', "%{$userId}%");
if ($parkId !== '')
$q->where('r.park_id', 'like', "%{$parkId}%");
if ($fromDt)
$q->whereDate('r.reserve_date', '>=', $fromDt);
if ($toDt)
$q->whereDate('r.reserve_date', '<=', $toDt);
if ($keyword !== '') {
$q->where(function ($w) use ($keyword) {
$w->where('u.user_name', 'like', "%{$keyword}%")
->orWhere('u.user_phonetic', 'like', "%{$keyword}%");
});
}
// ソート許可カラムJOIN 先も含む)
$sortable = [
'reserve_id',
'contract_id',
'user_id',
'park_id',
'reserve_date',
'reserve_start',
'reserve_end',
'reserve_cancelday',
'valid_flag',
'ope_id',
'user_name',
'user_phonetic',
'user_mobile',
'park_name',
];
if (!in_array($sort, $sortable, true))
$sort = 'reserve_id';
$sortMap = [
'user_name' => 'u.user_name',
'user_phonetic' => 'u.user_phonetic',
'user_mobile' => 'u.user_mobile',
'park_name' => 'p.park_name',
];
$sortCol = $sortMap[$sort] ?? ('r.' . $sort);
$list = $q->orderBy($sortCol, $sortType)->paginate(50);
return view('admin.reserves.list', [
'list' => $list,
'sort' => $sort,
'sort_type' => $sortType,
// 入力保持
'user_id' => $userId,
'park_id' => $parkId,
'reserve_date_from' => $fromDt,
'reserve_date_to' => $toDt,
'keyword' => $keyword,
]);
}
/**
* 予約追加GET: 画面表示 / POST: 登録)
*/
public function add(Request $request)
{
if ($request->isMethod('get')) {
return view('admin.reserves.add');
}
// 予約の最低限バリデーション(必要に応じて追加)
$v = Validator::make($request->all(), [
'user_id' => ['required', 'integer'],
'park_id' => ['required', 'integer'],
'reserve_date' => ['nullable', 'date'],
'reserve_start' => ['nullable', 'date'],
'reserve_end' => ['nullable', 'date'],
], [], [
'user_id' => '利用者ID',
'park_id' => '駐輪場ID',
]);
if ($v->fails()) {
return back()->withErrors($v)->withInput();
}
DB::table('reserve')->insert([
'user_id' => (int) $request->input('user_id'),
'park_id' => (int) $request->input('park_id'),
'contract_id' => $request->input('contract_id'), // 任意regular_contract と紐づける場合【turn12file7†L20-L28】
'price_parkplaceid' => $request->input('price_parkplaceid'),
'psection_id' => $request->input('psection_id'),
'reserve_date' => $request->input('reserve_date'),
'reserve_start' => $request->input('reserve_start'),
'reserve_end' => $request->input('reserve_end'),
'valid_flag' => $request->input('valid_flag'),
'ope_id' => $request->input('ope_id'),
'created_at' => now(),
'updated_at' => now(),
]);
return redirect()->route('reserves')->with('success', '予約を登録しました。');
}
/**
* 予約削除
*/
public function delete(Request $request)
{
$normalizeIds = function ($raw) {
if (is_string($raw)) {
$raw = explode(',', $raw);
}
if (is_array($raw) && count($raw) === 1 && is_string($raw[0]) && str_contains($raw[0], ',')) {
$raw = explode(',', $raw[0]);
}
$ids = array_map('intval', (array) $raw);
$ids = array_values(array_unique(array_filter($ids, fn($v) => $v > 0)));
return $ids;
};
if ($request->isMethod('get')) {
$ids = $normalizeIds($request->input('ids', []));
$rows = [];
if ($ids) {
$rows = DB::table('reserve as r')
->leftJoin('user as u', 'u.user_id', '=', 'r.user_id')
->leftJoin('park as p', 'p.park_id', '=', 'r.park_id')
->whereIn('r.reserve_id', $ids)
->select('r.*', 'u.user_name', 'p.park_name')
->get();
}
return view('admin.reserves.delete', compact('rows', 'ids'));
}
if ($request->post('confirmed')) {
$ids = $normalizeIds($request->input('ids', []));
if ($ids) {
$deleted = DB::table('reserve')->whereIn('reserve_id', $ids)->delete();
return redirect()->route('reserves')->with(
$deleted ? 'success' : 'warning',
$deleted ? "{$deleted} 件を削除しました。" : '対象が見つかりませんでした。'
);
}
}
return redirect()->route('reserves')->with('warning', '削除対象がありません。');
}
public function edit(Request $request, $reserve_id)
{
$id = (int) $reserve_id;
// 取得レコード無ければ404
$row = DB::table('reserve')->where('reserve_id', $id)->first();
if (!$row) {
abort(404);
}
// POST: 更新処理※reserveテーブルに確実にある列だけ更新
if ($request->isMethod('post')) {
$v = Validator::make($request->all(), [
'user_id' => ['required', 'integer'],
'park_id' => ['required', 'integer'],
'reserve_date' => ['nullable', 'date'],
'reserve_start' => ['nullable', 'date'],
'reserve_end' => ['nullable', 'date'],
], [], [
'user_id' => '利用者ID',
'park_id' => '駐輪場ID',
]);
if ($v->fails()) {
return back()->withErrors($v)->withInput();
}
$data = [
'contract_id' => $request->input('contract_id'),
'user_id' => (int) $request->input('user_id'),
'park_id' => (int) $request->input('park_id'),
'price_parkplaceid' => $request->input('price_parkplaceid'),
'psection_id' => $request->input('psection_id'),
'reserve_date' => $request->input('reserve_date'),
'reserve_start' => $request->input('reserve_start'),
'reserve_end' => $request->input('reserve_end'),
'valid_flag' => $request->input('valid_flag'),
'ope_id' => $request->input('ope_id'),
'updated_at' => now(),
];
DB::table('reserve')->where('reserve_id', $id)->update($data);
return redirect()->route('reserves')->with('success', '予約を更新しました。');
}
// GET: 編集画面表示用の各種プルダウン(存在するテーブルだけ読む)
$userOptions = DB::table('user')
->orderBy('user_id', 'asc')
->limit(5000)
->pluck(DB::raw("concat(user_id, ' ', user_name)"), 'user_id')
->toArray();
$parkOptions = DB::table('park')
->orderBy('park_id', 'asc')
->limit(5000)
->pluck(DB::raw("concat(park_id, ' ', park_name)"), 'park_id')
->toArray();
$userTypeOptions = Schema::hasTable('usertype')
? DB::table('usertype')->orderBy('user_categoryid')
->pluck('print_name', 'user_categoryid')->toArray()
: [];
$parkplaceOptions = Schema::hasTable('price_parkplace')
? DB::table('price_parkplace')->orderBy('price_parkplaceid')
->pluck('price_parkplaceid', 'price_parkplaceid')->toArray()
: [];
$psectionOptions = Schema::hasTable('psection')
? DB::table('psection')->orderBy('psection_id')
->pluck(
Schema::hasColumn('psection', 'psection_name') ? 'psection_name' : 'psection_id',
'psection_id'
)->toArray()
: [];
$ptypeOptions = Schema::hasTable('ptype')
? DB::table('ptype')->orderBy('ptype_id')
->pluck(
Schema::hasColumn('ptype', 'ptype_name') ? 'ptype_name' : 'ptype_id',
'ptype_id'
)->toArray()
: [];
return view('admin.reserves.edit', compact(
'row',
'userOptions',
'parkOptions',
'userTypeOptions',
'parkplaceOptions',
'psectionOptions',
'ptypeOptions'
));
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class UpdateCandidateController extends Controller
{
/**
* 更新予定者一覧表示
*/
public function list(Request $request)
{
$q = DB::table('regular_contract as rc')
->select([
'rc.contract_id',
'rc.contract_qr_id',
'rc.user_id',
'rc.user_categoryid',
'rc.park_id',
'rc.contract_created_at',
'rc.contract_periods',
'rc.contract_periode',
'rc.tag_qr_flag',
'rc.contract_flag',
'rc.contract_cancel_flag',
'rc.contract_payment_day',
'rc.contract_money',
'rc.billing_amount',
'rc.contract_permission',
'rc.contract_manual',
'rc.contract_notice',
'p.park_name',
'u.user_name',
'u.user_phonetic',
'u.user_mobile',
'u.user_homephone',
'u.user_primemail',
'u.user_gender',
'u.user_birthdate',
'u.user_regident_zip',
'u.user_regident_pre',
'u.user_regident_city',
'u.user_regident_add',
'u.user_relate_zip',
'u.user_relate_pre',
'u.user_relate_city',
'u.user_relate_add',
'u.user_graduate',
'u.user_workplace',
'u.user_school',
'u.user_remarks',
])
->leftJoin('park as p', 'rc.park_id', '=', 'p.park_id')
->leftJoin('user as u', 'rc.user_id', '=', 'u.user_id')
->whereNull('rc.update_flag'); // 未更新のみ
// 対象月による有効期限の絞り込み
if ($request->filled('target_month')) {
$now = now();
switch ($request->input('target_month')) {
case 'last':
$start = $now->copy()->subMonth()->startOfMonth();
$end = $now->copy()->subMonth()->endOfMonth();
break;
case 'this':
$start = $now->copy()->startOfMonth();
$end = $now->copy()->endOfMonth();
break;
case 'next':
$start = $now->copy()->addMonth()->startOfMonth();
$end = $now->copy()->addMonth()->endOfMonth();
break;
case 'after2':
$start = $now->copy()->addMonths(2)->startOfMonth();
$end = $now->copy()->addMonths(2)->endOfMonth();
break;
default:
$start = null;
$end = null;
}
if ($start && $end) {
$q->whereBetween('rc.contract_periode', [$start->toDateString(), $end->toDateString()]);
}
}
$sort = $request->input('sort', 'rc.contract_id');
$sortType = $request->input('sort_type', 'desc');
$allowSorts = ['rc.contract_id'];
if (!in_array($sort, $allowSorts)) {
$sort = 'rc.contract_id';
}
$sortType = ($sortType === 'asc') ? 'asc' : 'desc';
$rows = $q->orderBy($sort, $sortType)->paginate(20)->withQueryString();
// 駐輪場リスト(プルダウン用)
$parks = DB::table('park')->select('park_id', 'park_name')->orderBy('park_name')->get();
return view('admin.update_candidate.list', compact('rows', 'sort', 'sortType', 'parks'));
}
}

View File

@ -0,0 +1,318 @@
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\StreamedResponse;
class UsersController
{
/**
* 利用者一覧
* - テーブル名: user
* - 主キー: user_seqAUTO_INCREMENT:contentReference[oaicite:3]{index=3}
* - よく使う表示項目のみ選択(必要に応じて拡張)
*/
// 先确保use App\Http\Controllers\Controller; を追加し、必要なら extends Controller にする
// use Symfony\Component\HttpFoundation\StreamedResponse; は既にOK
/**
* 一覧(絞り込み + ページング)
*/
public function list(Request $request)
{
// ▼ 並び順(ホワイトリスト)
$sortable = [
'user_seq',
'user_id',
'member_id',
'contract_number',
'user_tag_serial',
'user_tag_serial_64',
'qr_code',
'tag_qr_flag',
'user_aid',
'user_place_qrid',
'user_categoryid',
'user_name',
'user_birthdate',
'user_age',
'user_homephone',
'user_primemail',
'user_submail',
'user_school',
];
$sort = $request->input('sort', 'user_seq');
$sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc';
if (!in_array($sort, $sortable, true)) {
$sort = 'user_seq';
}
// ▼ 絞り込み値('' のときだけ無視。'0' は有効値として扱う)
$user_id = trim((string) $request->input('user_id', ''));
$member_id = trim((string) $request->input('member_id', ''));
$user_tag_serial = trim((string) $request->input('user_tag_serial', ''));
$user_phonetic = trim((string) $request->input('user_phonetic', ''));
$phone = trim((string) $request->input('phone', '')); // 携帯/自宅の両方対象
$crime = trim((string) $request->input('crime', '')); // 防犯登録番号(暫定: qr_code
$user_categoryid = (string) $request->input('user_categoryid', '');
$tag_qr_flag = (string) $request->input('tag_qr_flag', ''); // 0=タグ / 1=QR
$quit_flag = (string) $request->input('quit_flag', ''); // 0=いいえ / 1=はい
$quit_from = (string) $request->input('quit_from', ''); // YYYY-MM-DD
$quit_to = (string) $request->input('quit_to', ''); // YYYY-MM-DD
// ▼ ベースクエリ(一覧で使う列が多いので一旦 * を許容)
$query = DB::table('user')->select('user.*');
// ▼ テキスト系
if ($user_id !== '')
$query->where('user.user_id', 'like', "%{$user_id}%");
if ($member_id !== '')
$query->where('user.member_id', 'like', "%{$member_id}%");
if ($user_tag_serial !== '')
$query->where('user.user_tag_serial', 'like', "%{$user_tag_serial}%");
if ($user_phonetic !== '')
$query->where('user.user_phonetic', 'like', "%{$user_phonetic}%");
if ($phone !== '') {
$query->where(function ($w) use ($phone) {
$w->where('user.user_mobile', 'like', "%{$phone}%")
->orWhere('user.user_homephone', 'like', "%{$phone}%");
});
}
if ($crime !== '') {
// ※ dump に防犯登録番号の明確なカラムが無いため暫定的に qr_code を対象
$query->where('user.qr_code', 'like', "%{$crime}%");
}
// ▼ セレクト/ラジオ('' 以外なら適用。'0' も通す)
if ($user_categoryid !== '')
$query->where('user.user_categoryid', $user_categoryid);
if ($tag_qr_flag !== '')
$query->where('user.tag_qr_flag', (int) $tag_qr_flag);
if ($quit_flag !== '')
$query->where('user.user_quit_flag', (int) $quit_flag);
// ▼ 日付範囲(退会日)
if ($quit_from !== '')
$query->where('user.user_quitday', '>=', $quit_from);
if ($quit_to !== '')
$query->where('user.user_quitday', '<=', $quit_to);
// ▼ 並び & ページング
$list = $query->orderBy("user.{$sort}", $sortType)->paginate(20);
// ▼ 画面に渡す(フォーム再描画用に絞り込み値も)
return view('admin.users.list', [
'list' => $list,
'sort' => $sort,
'sort_type' => $sortType,
'user_id' => $user_id,
'member_id' => $member_id,
'user_tag_serial' => $user_tag_serial,
'user_phonetic' => $user_phonetic,
'phone' => $phone,
'crime' => $crime,
'user_categoryid' => $user_categoryid,
'tag_qr_flag' => $tag_qr_flag,
'quit_flag' => $quit_flag,
'quit_from' => $quit_from,
'quit_to' => $quit_to,
]);
}
/**
* CSV 出力(一覧と同じ絞り込みを適用)
*/
public function export(Request $request): StreamedResponse
{
$q = DB::table('user');
// ▼ テキスト系
if (($v = trim((string) $request->input('user_id', ''))) !== '')
$q->where('user_id', 'like', "%{$v}%");
if (($v = trim((string) $request->input('user_tag_serial', ''))) !== '')
$q->where('user_tag_serial', 'like', "%{$v}%");
if (($v = trim((string) $request->input('user_phonetic', ''))) !== '')
$q->where('user_phonetic', 'like', "%{$v}%");
if (($v = trim((string) $request->input('phone', ''))) !== '') {
$q->where(function ($w) use ($v) {
$w->where('user_mobile', 'like', "%{$v}%")
->orWhere('user_homephone', 'like', "%{$v}%");
});
}
if (($v = trim((string) $request->input('email', ''))) !== '')
$q->where('user_primemail', 'like', "%{$v}%");
// ▼ セレクト/ラジオ('' だけスキップ。'0' は適用)
$val = (string) $request->input('user_categoryid', '');
if ($val !== '')
$q->where('user_categoryid', $val);
$val = (string) $request->input('tag_qr_flag', '');
if ($val !== '')
$q->where('tag_qr_flag', (int) $val);
$val = (string) $request->input('quit_flag', '');
if ($val !== '')
$q->where('user_quit_flag', (int) $val);
// ▼ 退会日 範囲
if (($from = (string) $request->input('quit_from', '')) !== '')
$q->where('user_quitday', '>=', $from);
if (($to = (string) $request->input('quit_to', '')) !== '')
$q->where('user_quitday', '<=', $to);
// ▼ 取得・並び
$q->orderBy('user_seq', 'desc');
$rows = $q->get([
'user_id',
'tag_qr_flag',
'user_categoryid',
'user_name',
'user_phonetic',
'user_birthdate',
'user_age',
'user_mobile',
'user_homephone',
'user_primemail',
'user_idcard',
'user_idcard_chk_flag',
'user_chk_day',
'user_quit_flag',
'user_quitday',
]);
$headers = [
'利用者ID',
'タグ/QRフラグ',
'利用者分類ID',
'利用者名',
'フリガナ',
'生年月日',
'年齢',
'携帯電話番号',
'自宅電話番号',
'メールアドレス',
'本人確認書類',
'本人確認チェック済',
'本人確認日時',
'退会フラグ',
'退会日',
];
$filename = 'users_' . date('Ymd_His') . '.csv';
return response()->streamDownload(function () use ($headers, $rows) {
// ▼ BOMExcel対策
echo "\xEF\xBB\xBF";
$out = fopen('php://output', 'w');
fputcsv($out, $headers);
foreach ($rows as $r) {
// ▼ 表示値変換
$tagQr = ((int) $r->tag_qr_flag === 1) ? '' : 'タグ';
$idChk = ((int) ($r->user_idcard_chk_flag ?? 0) === 1) ? '手動チェックOK' : '未チェック';
$quitFlg = ((int) $r->user_quit_flag === 1) ? 'はい' : 'いいえ';
$birth = $r->user_birthdate ? mb_substr($r->user_birthdate, 0, 10) : '';
$chkDay = $r->user_chk_day ? mb_substr($r->user_chk_day, 0, 10) : '';
$quitDay = $r->user_quitday ? mb_substr($r->user_quitday, 0, 10) : '';
fputcsv($out, [
$r->user_id,
$tagQr,
$r->user_categoryid,
$r->user_name,
$r->user_phonetic,
$birth,
$r->user_age,
$r->user_mobile,
$r->user_homephone,
$r->user_primemail,
$r->user_idcard,
$idChk,
$chkDay,
$quitFlg,
$quitDay,
]);
}
fclose($out);
}, $filename, [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]);
}
/**
* 利用者登録GET: 画面表示 / POST: 登録実行)
* - 必須は最小限user_id, user_name, user_gender, user_primemail
* - created_at/updated_at DB 側に任せるかここで now() を入れてもOK
*/
public function add(Request $request)
{
if ($request->isMethod('get')) {
return view('admin.users.add');
}
// ▼ バリデーションuser_id は半角数字のみ)
$rules = [
'user_id' => ['required', 'regex:/^\d+$/'], // 半角数字のみ許可
'user_name' => ['required', 'string', 'max:255'],
// 任意
'user_primemail' => ['nullable', 'email', 'max:255'],
'user_gender' => ['nullable', 'in:男性,女性'],
'member_id' => ['nullable', 'string', 'max:255'],
'user_mobile' => ['nullable', 'string', 'max:255'],
'user_homephone' => ['nullable', 'string', 'max:255'],
'user_birthdate' => ['nullable', 'date'],
'user_categoryid' => ['nullable', 'integer'],
];
// ▼ エラーメッセージ(日本語)
$messages = [
'user_id.required' => '利用者IDは必須です。',
'user_id.regex' => '利用者IDは半角数字のみで入力してください。',
];
// ▼ 属性名(日本語ラベル)
$attributes = [
'user_id' => '利用者ID',
'user_name' => '氏名',
'user_gender' => '性別',
'user_primemail' => '主メール',
];
$v = Validator::make($request->all(), $rules, $messages, $attributes);
if ($v->fails()) {
return back()->withErrors($v)->withInput();
}
// 実在カラム名に合わせて挿入(不要なら削る/必要なら増やす)
$data = [
'user_id' => $request->input('user_id'),
'user_name' => $request->input('user_name'),
'user_gender' => $request->input('user_gender'),
'user_primemail' => $request->input('user_primemail'),
'member_id' => $request->input('member_id'),
'user_mobile' => $request->input('user_mobile'),
'user_homephone' => $request->input('user_homephone'),
'user_birthdate' => $request->input('user_birthdate'),
'user_categoryid' => $request->input('user_categoryid'),
'created_at' => now(),
'updated_at' => now(),
];
DB::table('user')->insert($data);
return redirect()->route('users')->with('success', '利用者を登録しました。');
}
}

View File

@ -0,0 +1,291 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Requests\UsertypeRequest;
use App\Models\Usertype;
use App\Utils;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Response;
class UsertypeController extends Controller
{
public function list(Request $request)
{
$inputs = [
'isMethodPost' => 0,
'isExport' => 0,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
'page' => $request->get('page', 1),
];
$inputs['isMethodPost'] = $request->isMethod('post');
$inputs['list'] = Usertype::search($inputs);
if ($inputs['list']->total() > 0 && $inputs['page'] > $inputs['list']->lastPage()) {
return redirect()->route('usertypes');
}
return view('admin.usertypes.list', $inputs);
}
public function add(Request $request)
{
// 画面に戻すための初期値
$viewData = [
'sort_order' => old('sort_order', ''),
'category_name1' => old('category_name1', ''),
'category_name2' => old('category_name2', ''),
'category_name3' => old('category_name3', ''),
'print_name' => old('print_name', ''),
'usertype_money' => old('usertype_money', ''),
'usertype_remarks' => old('usertype_remarks', ''),
'isEdit' => 0,
'isInfo' => 0,
];
if ($request->isMethod('post')) {
// 入力値をまとめる
$inputs = [
'sort_order' => $request->input('sort_order'),
'category_name1' => $request->input('category_name1'),
'category_name2' => $request->input('category_name2'),
'category_name3' => $request->input('category_name3'),
'print_name' => $request->input('print_name'),
'usertype_money' => $request->input('usertype_money'),
'usertype_remarks' => $request->input('usertype_remarks'),
];
// バリデーションルール(最小限)
$rules = [
'sort_order' => 'nullable|integer',
'category_name1' => 'nullable|string|max:255',
'category_name2' => 'nullable|string|max:255',
'category_name3' => 'nullable|string|max:255',
'print_name' => 'required|string|max:255',
'usertype_money' => 'nullable|string|max:255',
'usertype_remarks' => 'nullable|string|max:255',
];
$messages = [
'print_name.required' => '印字名は必須です。',
'sort_order.integer' => 'ソートオーダーは数値で入力してください。',
];
$validator = Validator::make($inputs, $rules, $messages);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
// 登録処理
$ok = false;
\DB::transaction(function () use ($inputs, &$ok) {
$new = new Usertype();
$new->fill($inputs);
$ok = $new->save();
});
if ($ok) {
return redirect()->route('usertypes')->with('success', '登録しました。');
}
return back()->with('error', '登録に失敗しました。')->withInput();
}
// GET: 画面表示
return view('admin.usertypes.add', $viewData);
}
public function edit(Request $request, $id)
{
$usertype = Usertype::findOrFail($id);
// 画面に渡す初期データ(既存の構成に合わせて attributes を使う)
$data = $usertype->getAttributes();
if (method_exists($this, 'getDataDropList')) {
$dataList = $this->getDataDropList();
$data = array_merge($data, $dataList);
}
if ($request->isMethod('POST')) {
$type = false;
// ▼ 内蔵バリデーションFormRequest を使わない)
$rules = [
'sort_order' => 'nullable|integer',
'category_name1' => 'nullable|string|max:255',
'category_name2' => 'nullable|string|max:255',
'category_name3' => 'nullable|string|max:255',
'print_name' => 'required|string|max:255',
'usertype_money' => 'nullable|string|max:255',
'usertype_remarks' => 'nullable|string|max:255',
];
$messages = [
'print_name.required' => '印字名は必須です。',
'sort_order.integer' => 'ソートオーダーは数値で入力してください。',
];
$validator = Validator::make($request->all(), $rules, $messages);
// 入力値を $data にマージ(既存ロジック踏襲)
$requestAll = $request->all();
$data = array_merge($data, $requestAll);
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
\DB::transaction(function () use ($data, &$type, $usertype) {
// fill するフィールドだけを明示したい場合は only(...) で絞ってもOK
$usertype->fill([
'sort_order' => $data['sort_order'] ?? null,
'category_name1' => $data['category_name1'] ?? null,
'category_name2' => $data['category_name2'] ?? null,
'category_name3' => $data['category_name3'] ?? null,
'print_name' => $data['print_name'] ?? null,
'usertype_money' => $data['usertype_money'] ?? null,
'usertype_remarks' => $data['usertype_remarks'] ?? null,
]);
$usertype->save();
$type = true;
});
if ($type) {
return redirect()->route('usertypes')->with('success', '更新しました。');
}
return back()->with('error', '更新に失敗しました。')->withInput();
}
// GET: 画面表示(既存のビューに合わせて返す)
return view('admin.usertypes.edit', $data);
}
public function delete(Request $request)
{
// pk[] が無ければ ids[] を見る(両対応)
$arr_pk = $request->input('pk');
if (empty($arr_pk)) {
$arr_pk = $request->input('ids', []);
}
if (!is_array($arr_pk)) {
$arr_pk = [$arr_pk];
}
if (empty($arr_pk)) {
return redirect()->route('usertypes')->with('error', '削除するユーザーを選択してください。');
}
if (Usertype::deleteByPk($arr_pk)) {
return redirect()->route('usertypes')->with('success', '削除が完了しました。');
}
return redirect()->route('usertypes')->with('error', '削除に失敗しました。');
}
public function info(Request $request, $id)
{
return $this->edit($request, $id, 'admin.usertypes.info');
}
public function getDataDropList()
{
$data = [];
return $data;
}
public function export(Request $request)
{
$headers = array(
"Content-type" => "text/csv;charset=UTF-8",
'Content-Encoding: UTF-8',
"Content-Disposition" => "attachment; filename=file.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
'sort' => $request->input('sort', ''),
'sort_type' => $request->input('sort_type', ''),
];
$dataExport = Usertype::search($inputs);
$columns = array(
__('利用者分類ID'),// 0
__('分類名'),// 1
__('適用料率'),// 2
__('備考'),// 3
);
$filename = "利用者分類マスタ.csv";
$file = fopen($filename, 'w+');
fputcsv($file, $columns);
foreach ($dataExport as $items) {
fputcsv(
$file,
array(
$items->user_categoryid,
$items->print_name,
$items->usertype_money,
$items->usertype_remarks, // 3
)
);
}
fclose($file);
return Response::download($filename, $filename, $headers);
}
public function import(Request $request)
{
$file = $request->file('file');
if (!empty($file)) {
$data = Utils::csvToArray($file);
$type = 1;
$msg = '';
$record = 0;
DB::beginTransaction();
try {
Usertype::query()->delete();
$col = 4;
foreach ($data as $key => $items) {
$record = $key + 2;
if (count($items) == $col) {
$row = new Usertype();
$row->user_categoryid = $items[0];
$row->print_name = $items[1];
$row->usertype_money = $items[2];
$row->usertype_remarks = $items[3];
if (!$row->save()) {
$type = 0;
$msg = '行:record型が一致しません。';
break;
}
} else {
$type = 0;
$msg = '行:record列数が一致しません。';
break;
}
}
} catch (\Exception $e) {
dd($e);
$msg = '行:record型が一致しません。';
$type = 0;
}
if ($type) {
DB::commit();
return redirect()->route('usertypes')->with('success', __('輸入成功'));
} else {
DB::rollBack();
return redirect()->route('usertypes')->with('error', __($msg, ['record' => $record]));
}
} else {
return redirect()->route('usertypes')->with('error', __('あなたはcsvファイルを選択していません。'));
}
}
}

34
app/Models/City.php Normal file
View File

@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
protected $table = 'city';
public $timestamps = true;
protected $primaryKey = 'city_id';
protected $fillable = [
'city_id',
'city_name',
'print_layout',
'city_user',
'city_remarks',
'created_at',
'updated_at',
];
/**
* 都市のリストを取得
*/
public static function getList()
{
return self::all();
}
}

105
app/Models/Price.php Normal file
View File

@ -0,0 +1,105 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class Price extends Model
{
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
const PRICE_MONTH = [
1 => '1ヶ月',
2 => '2ヶ月',
3 => '3ヶ月',
4 => '6ヶ月',
5 => '12ヶ月',
];
protected $table = 'price_a';
protected $primaryKey = 'price_parkplaceid';
protected $fillable = [
'prine_name',
'price_month',
'park_id',
'psection_id',
'price_ptypeid',
'user_categoryid',
'pplace_id',
'price'
];
public static function boot()
{
parent::boot();
self::creating(function (Price $model) {
$model->operator_id = Auth::user()->ope_id;
});
}
public static function search($inputs)
{
$list = self::query();
// 只有在sort是有效字段时才排序
$allowedSortColumns = [
'price_parkplaceid',
'prine_name',
'price_month',
'park_id',
'psection_id',
'price_ptypeid',
'user_categoryid',
'pplace_id',
'price'
];
$sort_column = $inputs['sort'] ?? '';
$sort_type = strtolower($inputs['sort_type'] ?? 'asc');
if (in_array($sort_column, $allowedSortColumns)) {
if (!in_array($sort_type, ['asc', 'desc'])) {
$sort_type = 'asc';
}
$list->orderBy($sort_column, $sort_type);
}
if ($inputs['isExport']) {
$list = $list->get();
} else {
$list = $list->paginate(Utils::item_per_page);
}
return $list;
}
public static function getByPk($pk)
{
return self::find($pk);
}
public static function deleteByPk($arr)
{
return self::whereIn('price_parkplaceid', $arr)->delete();
}
//TODO 駐車場所ID not found in database specs
//TODO 駐車車室ID not found in database specs
public function getPark()
{
return $this->belongsTo(Park::class, 'park_id', 'park_id')->first();
}
public function getPSection()
{
return $this->belongsTo(Psection::class, 'psection_id', 'psection_id')->first();
}
public function getPType()
{
return $this->belongsTo(Ptype::class, 'price_ptypeid', 'ptype_id')->first();
}
public function getUserType()
{
return $this->belongsTo(Usertype::class, 'user_categoryid', 'user_categoryid')->first();
}
}

25
app/Models/PriceB.php Normal file
View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PriceB extends Model
{
protected $table = 'price_b';
protected $primaryKey = 'price_parkplaceid';
public $timestamps = true;
protected $fillable = [
'park_id', 'price_ptypeid', 'user_categoryid', 'price_month',
'price', 'prine_name', 'psection_id', 'pplace_id', 'operator_id',
];
/**
* 指定駐輪場IDの料金データ取得スコープ
*/
public function scopeForPark($query, $parkId)
{
return $query->where('park_id', $parkId);
}
}

22
app/Models/PriceList.php Normal file
View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PriceList extends Model
{
// テーブル名
protected $table = 'price_list'; // 実際のテーブル名に合わせて修正
// 主キー
protected $primaryKey = 'id';
// タイムスタンプ自動管理(必要なら true、不要なら false
public $timestamps = false;
// 一括代入許可カラム
protected $guarded = []; // もしくは ['id'] のように制限
// 必要に応じてリレーションやアクセサ・ミューテタなど追加
}

144
app/Models/Psection.php Normal file
View File

@ -0,0 +1,144 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
/**
* 車種区分モデル - psectionテーブル
*
* 駐輪場の車種区分マスタデータを管理
*/
class Psection extends Model
{
/**
* テーブル名
*
* @var string
*/
protected $table = 'psection';
/**
* プライマリキー
*
* @var string
*/
protected $primaryKey = 'psection_id';
/**
* 一括代入可能な属性
*
* @var array
*/
protected $fillable = [
'psection_subject', // 車種区分名
'operator_id', // オペレータID
'created_at', // 作成日時
'updated_at', // 更新日時
'psection_id' // 車種区分ID
];
/**
* キャストする属性
*
* @var array
*/
protected $casts = [
'psection_id' => 'integer',
'operator_id' => 'integer',
'created_at' => 'datetime',
'updated_at' => 'datetime'
];
// 主キーが自動増分でない場合はfalseに設定
public $incrementing = false;
// タイムスタンプ管理しない場合はfalseに設定
public $timestamps = false;
/**
* 売上集計との関連
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function earningsSummaries()
{
return $this->hasMany(EarningsSummary::class, 'psection_id', 'psection_id');
}
/**
* 定期契約との関連
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function regularContracts()
{
return $this->hasMany(RegularContract::class, 'psection_id', 'psection_id');
}
/**
* アクティブな車種区分一覧を取得
*
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function getActivePsections()
{
return self::orderBy('psection_id')->get();
}
/**
* 車種区分名で検索
*
* @param string $subject 車種区分名
* @return Psection|null
*/
public static function findBySubject(string $subject): ?Psection
{
return self::where('psection_subject', $subject)->first();
}
/**
* 文字列表現
*
* @return string
*/
public function __toString(): string
{
return sprintf(
'Psection[ID:%d, Subject:%s]',
$this->psection_id,
$this->psection_subject
);
}
// 新規作成時にoperator_idを自動設定operator_idカラムがある場合のみ
public static function boot()
{
parent::boot();
self::creating(function (Psection $model) {
// ログインしている場合のみセット
if (\Auth::check()) {
$model->operator_id = Auth::user()->ope_id;
}
});
}
// 車種区分リストを取得(プルダウン用)
public static function getList()
{
return self::orderBy('psection_id')->pluck('psection_subject', 'psection_id');
}
}

66
app/Models/Usertype.php Normal file
View File

@ -0,0 +1,66 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class Usertype extends Model
{
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
const PERPAGE = 50;
protected $table = 'usertype';
protected $primaryKey = 'user_categoryid';
protected $fillable = [
'print_name',
'usertype_money',
'usertype_remarks'
];
public static function boot()
{
parent::boot();
self::creating(function (Usertype $model) {
$model->operator_id = Auth::user()->ope_id;
});
}
public static function search($inputs)
{
$list = self::query();
if ($inputs['isMethodPost']) {
}
// Sort
if ($inputs['sort']) {
$list->orderBy($inputs['sort'], $inputs['sort_type']);
}
if ($inputs['isExport']){
$list = $list->get();
}else{
$list = $list->paginate(Utils::item_per_page);
}
return $list;
}
public static function getByPk($pk)
{
return self::find($pk);
}
public static function deleteByPk($arr)
{
return self::whereIn('user_categoryid', $arr)->delete();
}
//TODO 利用者分類ID not found in database specs
//TODO 利用者分類名 not found in database specs
public static function getList(){
return self::pluck('print_name','user_categoryid');
}
}

134
app/Models/Utils.php Normal file
View File

@ -0,0 +1,134 @@
<?php
/**
* ユーティリティクラス
* Laravel 5.7から引き継いだヘルパー機能
* Created by PhpStorm.
* User: mrpha
* Date: 5/31/2016
* Time: 1:49 PM
*/
namespace App\Models;
use File;
use Illuminate\Support\Facades\Hash;
/**
* 共通ユーティリティクラス
* ファイルアップロード、パスワード暗号化、CSV処理など
*/
class Utils
{
// ページあたりのアイテム数(旧システムから継承)
const item_per_page = 50;
// 画像保存パス(旧システムから継承)
const image_path = 'storage/images/';
/**
* 画像ファイルをimagesフォルダにアップロード
* Laravel 5.7から継承したメソッド
*
* @param \Illuminate\Http\UploadedFile $file アップロードファイル
* @param string|null $fileName ファイル名(指定しない場合は自動生成)
* @return string|false アップロード成功時はファイル名、失敗時はfalse
*/
public static function uploadFile($file, $fileName = null)
{
$destinationPath = self::getImagePath();
$date = strtotime(date('Y-m-d H:i:s'));
// ファイルをフォルダに移動
$fileName = $fileName . $date . '.' . $file->getClientOriginalExtension();
if ($file->move($destinationPath, $fileName)) {
$filePath = $destinationPath.$fileName;
if (file_exists($filePath)){
chmod($filePath, 0755); // ファイル権限設定
}
return $fileName;
}
return false;
}
/**
* 画像パスを取得
*
* @param string $filname ファイル名
* @return string 画像パス
*/
public static function getImagePath($filname = '')
{
$path = self::image_path;
if ($filname) $path .= $filname;
return $path;
}
/**
* 画像URLを取得
*
* @param string $filname ファイル名
* @return string 画像URL
*/
public static function getImageUrl($filname = '')
{
return url(self::getImagePath($filname));
}
/**
* パスワードのハッシュ化
* Laravel 12変更点Hashファサードを使用してハッシュ化
* Laravel 5.7: 独自のソルト処理を実装していた
*
* @param string $pw 平文パスワード
* @param string $seq ユーザーシーケンス(ソルト用)
* @return string ハッシュ化されたパスワード
*/
public static function getHashPassword($pw, $seq)
{
// 旧システムと同じソルト形式を維持
$salt = $seq.'SOMSALT';
// Laravel 12: Argon2ハッシュアルゴリズムを使用
return Hash::make($pw, [
'memory' => 1024,
'time' => 25,
'threads' => 2,
'salt' => $salt
]);
}
/**
* CSVファイルを配列に変換
* Laravel 5.7から継承したメソッド(データインポート用)
*
* @param string $filename CSVファイルパス
* @param string $delimiter 区切り文字(デフォルト:カンマ)
* @return array|false 変換された配列、またはfalse失敗時
*/
public static function csvToArray($filename = '', $delimiter = ',')
{
// ファイル存在確認
if (!file_exists($filename) || !is_readable($filename))
return false;
$header = null;
$data = array();
// CSVファイルを読み込み
if (($handle = fopen($filename, 'r')) !== false)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== false)
{
if (!$header)
$header = $row; // 最初の行はヘッダーとして扱う
else
$data[] = $row; // データ行として配列に追加
}
fclose($handle);
}
return $data;
}
}

View File

@ -0,0 +1,24 @@
<div class="form-group">
<label for="city_id">市区ID</label>
<input type="text" name="city_id" id="city_id" class="form-control" value="{{ old('city_id', $city->city_id ?? '') }}" readonly>
</div>
<div class="form-group">
<label for="city_name">市区名</label>
<input type="text" name="city_name" id="city_name" class="form-control" value="{{ old('city_name', $city->city_name ?? '') }}" required>
</div>
<div class="form-group">
<label for="print_layout">印字レイアウトファイル</label>
<input type="text" name="print_layout" id="print_layout" class="form-control" value="{{ old('print_layout', $city->print_layout ?? '') }}">
</div>
<div class="form-group">
<label for="city_user">顧客M入力不要フィールドID</label>
<input type="text" name="city_user" id="city_user" class="form-control" value="{{ old('city_user', $city->city_user ?? '') }}">
</div>
<div class="form-group">
<label for="city_remarks">備考</label>
<textarea name="city_remarks" id="city_remarks" class="form-control" rows="3">{{ old('city_remarks', $city->city_remarks ?? '') }}</textarea>
</div>

View File

@ -0,0 +1,43 @@
@extends('layouts.app')
@section('title', '[東京都|〇〇駐輪場] マスタ管理')
@section('content')
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">[東京都|〇〇駐輪場] マスタ管理</h1>
</div><!-- /.col -->
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="./index2.html">XX様info(ホーム)</a></li>
<li class="breadcrumb-item"><a href="./index3.html">[東京都|〇〇駐輪場]</a></li>
<li class="breadcrumb-item">マスタ管理</li>
<li class="breadcrumb-item active">市区マスタ</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<div class="container-fluid">
<h1 class="h4 mb-4 text-gray-800">市区マスタ 新規登録</h1>
<div class="card shadow mb-4">
<div class="card-body">
<form method="POST" action="{{ route('city_add') }}">
@csrf
@include('admin.CityMaster._form', ['isEdit' => 0, 'isInfo' => 0])
<div class="mt-3">
<button type="submit" class="btn btn-primary"
onclick="return confirm('登録してよろしいですか?');">登録</button>
<a href="{{ route('city') }}" class="btn btn-secondary">戻る</a>
</div>
</form>
</div>
</div>
</div>
@endsection

View File

@ -0,0 +1,54 @@
@extends('layouts.app')
@section('title', '市区マスタ編集')
@section('content')
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">[東京都|〇〇駐輪場] 市区マスタ</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">XX様info(ホーム)</a></li>
<li class="breadcrumb-item"><a href="#">[東京都|〇〇駐輪場]</a></li>
<li class="breadcrumb-item">マスタ管理</li>
<li class="breadcrumb-item active">市区マスタ</li>
</ol>
</div>
</div>
</div>
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<h1 class="h5 mb-4">市区マスタ 編集</h1>
@includeIf('common.flash')
<div class="card shadow mb-4">
<div class="card-body">
<form method="POST" action="{{ route('city_edit', ['id' => $city->city_id]) }}" enctype="multipart/form-data">
@csrf
@method('POST')
@include('admin.CityMaster._form', [
'isEdit' => 1,
'isInfo' => 0,
'city' => $city,
])
<div class="mt-3">
<button type="submit" class="btn btn-primary">更新</button>
<a href="{{ route('city') }}" class="btn btn-secondary">戻る</a>
</div>
</form>
</div>
</div>
</div>
</section>
@endsection

View File

@ -0,0 +1,51 @@
@extends('layouts.app')
@section('content')
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">[東京都|〇〇駐輪場] 市区マスタ</h1>
</div><!-- /.col -->
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="./index2.html">XX様info(ホーム)</a></li>
<li class="breadcrumb-item"><a href="./index3.html">[東京都|〇〇駐輪場]</a></li>
<li class="breadcrumb-item">マスタ管理</li>
<li class="breadcrumb-item active">市区マスタ</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<!-- SELECT2 EXAMPLE -->
<div class="row">
<div class="col-lg-12">
<div class="card">
<form method="post" action="{{ route('user_edit',['seq'=>$user_seq]) }}" enctype="multipart/form-data">
<!-- TOKEN FORM -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" >
<!-- / .TOKEN FORM -->
@include('admin.users._form',['isEdit'=>0,'isInfo'=>1])
</form>
</div>
</div>
</div>
<div class="container-fluid mb20">
<button type="submit" class="btn btn-sm btn-default mr10">新規</button>
<button type="submit" class="btn btn-sm btn-default mr10">削除</button>
</div>
</div>
</section>
<!-- /.content -->
@endsection

View File

@ -0,0 +1,96 @@
@extends('layouts.app')
@section('title', '市区マスタ')
@section('content')
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">市区マスタ</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item active">市区マスタ</li>
</ol>
</div>
</div>
</div>
</div>
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<!-- Action Buttons -->
<div class="mb-3">
<a href="{{ route('city_add') }}" class="btn btn-sm btn-primary">新規</a>
<button type="submit" form="deleteForm" class="btn btn-sm btn-danger"
onclick="return confirm('選択した市区を削除しますか?');">削除</button>
</div>
@if ($list->count() > 0)
<form id="deleteForm" method="POST" action="{{ route('city_delete') }}">
@csrf
<div class="table-responsive ">
<table class="table table-bordered table-hover" >
<thead class="thead-light ">
<tr>
<th><input type="checkbox"
onclick="$('input[name*=\'pk\']').prop('checked', this.checked);"></th>
<th></th>
<th>
<a
href="{{ route('city', array_merge(request()->all(), ['sort' => 'city_id', 'sort_type' => $sort === 'city_id' && $sort_type === 'asc' ? 'desc' : 'asc'])) }}">
市区ID
@if($sort === 'city_id')
<i class="fa fa-sort-{{ $sort_type }}"></i>
@endif
</a>
</th>
<th>
<a
href="{{ route('city', array_merge(request()->all(), ['sort' => 'city_name', 'sort_type' => $sort === 'city_name' && $sort_type === 'asc' ? 'desc' : 'asc'])) }}">
市区名
@if($sort === 'city_name')
<i class="fa fa-sort-{{ $sort_type }}"></i>
@endif
</a>
</th>
<th>印字レイアウトファイル</th>
<th>顧客M入力不要フィールドID</th>
<th>備考</th>
</tr>
</thead>
<tbody>
@foreach ($list as $city)
<tr>
<td style="background: #faebd7;">
<input type="checkbox" name="pk[]" value="{{ $city->city_id }}">
<a href="{{ route('city_edit', ['id' => $city->city_id]) }}"
class="btn btn-sm btn-outline-primary ml-2">編集</a>
</td>
<td>{{ $city->city_id }}</td>
<td>{{ $city->city_name }}</td>
<td>{{ $city->print_layout }}</td>
<td>{{ $city->city_user }}</td>
<td>{{ $city->city_remarks }}</td>
<td> </td>
</tr>
@endforeach
</tbody>
</table>
</div>
</form>
<div class="mt-3">
{{ $list->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
@else
<div class="alert alert-info mt-4">表示する市区データがありません。</div>
@endif
</div>
</section>
@endsection

View File

@ -0,0 +1,17 @@
<!-- resources/views/pricelist/add.blade.php -->
@extends('layouts.app')
@section('content')
<div class="container">
<h2>金額更新</h2>
<form method="POST" action="{{ route('pricelist_update') }}">
@csrf
<!-- 金额相关的输入框等 -->
<div class="form-group">
<label for="amount">新しい金額</label>
<input type="text" name="amount" id="amount" class="form-control">
</div>
<button type="submit" class="btn btn-success">更新</button>
</form>
</div>
@endsection

View File

@ -0,0 +1,129 @@
@extends('layouts.app')
@section('content')
<div class="container-fluid">
{{-- ログインボタン --}}
<div style="position:absolute; right:32px; top:24px; z-index:2;">
<a href="{{ route('login') }}" class="btn btn-outline-primary btn-sm">ログイン</a>
</div>
<h3 class="mb-4">料金一覧表</h3>
{{-- 上部ツールバー:左=駐輪場セレクト、右(同列)=登録 --}}
<div class="d-flex align-items-center mb-3">
{{-- 駐輪場選択GET --}}
<form method="GET" action="{{ route('pricelist') }}" class="form-inline mb-0">
<label for="park_id" class="mr-2">駐輪場</label>
<select name="park_id" id="park_id" class="form-control mr-2 select-park" style="min-width:220px;"
onchange="this.form.submit()">
<option value="" @if(empty($parkId)) selected @endif></option>
@foreach($parkList as $park)
<option value="{{ $park->park_id }}" @if((string)$parkId === (string)$park->park_id) selected @endif>
{{ $park->park_name }}
</option>
@endforeach
</select>
</form>
{{-- 登録POST フォームを指定して送信) --}}
<button type="submit"
class="btn btn-primary btn-sm ml-3"
form="bulkUpdateForm">登録</button>
</div>
{{-- 一括更新フォームPOST --}}
<form id="bulkUpdateForm"
method="POST"
action="{{ route('pricelist_update') }}"
onsubmit="return confirm('登録してよろしいですか?');">
@csrf
{{-- 必要なら park_id を一緒に送る --}}
<input type="hidden" name="park_id" value="{{ $parkId }}">
@if(isset($masterList) && count($masterList))
@foreach($masterList as $master)
<div class="mb-4">
<div style="font-weight:bold;font-size:1.1em;">
{{ $master['name'] }}
<button type="button" class="btn btn-warning btn-sm ml-2" disabled>{{ $master['status'] }}</button>
</div>
<div class="table-responsive" style="overflow-x:auto; min-width:1300px;">
<table class="table table-bordered table-sm bg-white mt-2" style="min-width:1300px;">
<thead>
<tr>
<th rowspan="2">駐輪分類</th>
<th rowspan="2">駐輪車室番号</th>
<th rowspan="2">分類1</th>
<th rowspan="2">分類2</th>
<th rowspan="2">分類3</th>
<th colspan="5">自転車</th>
<th colspan="5">原付</th>
<th colspan="5">自動二輪</th>
</tr>
<tr>
<th>1ヶ月</th><th>2ヶ月</th><th>3ヶ月</th><th>6ヶ月</th><th>12ヶ月</th>
<th>1ヶ月</th><th>2ヶ月</th><th>3ヶ月</th><th>6ヶ月</th><th>12ヶ月</th>
<th>1ヶ月</th><th>2ヶ月</th><th>3ヶ月</th><th>6ヶ月</th><th>12ヶ月</th>
</tr>
</thead>
<tbody>
@forelse($master['groups'] as $group)
<tr>
<td>{{ $group['classification'] ?? '' }}</td>
<td>{{ $group['room_number'] ?? '' }}</td>
<td>{{ $group['category1'] ?? '' }}</td>
<td>{{ $group['category2'] ?? '' }}</td>
<td>{{ $group['category3'] ?? '' }}</td>
<input type="hidden" name="rows[{{ $group['id'] }}][id]" value="{{ $group['id'] }}">
{{-- 自転車 --}}
<td><input type="text" name="rows[{{ $group['id'] }}][bike_1m]" class="form-control form-control-sm price-input" value="{{ $group['bike_1m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][bike_2m]" class="form-control form-control-sm price-input" value="{{ $group['bike_2m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][bike_3m]" class="form-control form-control-sm price-input" value="{{ $group['bike_3m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][bike_6m]" class="form-control form-control-sm price-input" value="{{ $group['bike_6m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][bike_12m]" class="form-control form-control-sm price-input" value="{{ $group['bike_12m'] ?? '' }}"></td>
{{-- 原付 --}}
<td><input type="text" name="rows[{{ $group['id'] }}][moped_1m]" class="form-control form-control-sm price-input" value="{{ $group['moped_1m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][moped_2m]" class="form-control form-control-sm price-input" value="{{ $group['moped_2m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][moped_3m]" class="form-control form-control-sm price-input" value="{{ $group['moped_3m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][moped_6m]" class="form-control form-control-sm price-input" value="{{ $group['moped_6m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][moped_12m]" class="form-control form-control-sm price-input" value="{{ $group['moped_12m'] ?? '' }}"></td>
{{-- 自動二輪 --}}
<td><input type="text" name="rows[{{ $group['id'] }}][motorcycle_1m]" class="form-control form-control-sm price-input" value="{{ $group['motorcycle_1m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][motorcycle_2m]" class="form-control form-control-sm price-input" value="{{ $group['motorcycle_2m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][motorcycle_3m]" class="form-control form-control-sm price-input" value="{{ $group['motorcycle_3m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][motorcycle_6m]" class="form-control form-control-sm price-input" value="{{ $group['motorcycle_6m'] ?? '' }}"></td>
<td><input type="text" name="rows[{{ $group['id'] }}][motorcycle_12m]" class="form-control form-control-sm price-input" value="{{ $group['motorcycle_12m'] ?? '' }}"></td>
</tr>
@empty
<tr><td colspan="21" class="text-center">データがありません。</td></tr>
@endforelse
</tbody>
</table>
</div>
</div>
@endforeach
@else
<div class="mb-4">
<div class="table-responsive" style="overflow-x:auto; min-width:1300px;">
<table class="table table-bordered table-sm bg-white mt-2" style="min-width:1300px;">
<thead> …(省略:空表のヘッダは従来どおり)… </thead>
<tbody>
<tr><td colspan="21" class="text-center">データがありません。</td></tr>
</tbody>
</table>
</div>
</div>
@endif
</form>
</div>
<style>
.price-input:read-only{ background:#fff700!important; color:#222!important; border:1px solid #ccc; }
th{ white-space:nowrap!important; word-break:keep-all!important; font-size:13px; text-align:center; vertical-align:middle; min-width:50px; }
</style>
@endsection

View File

@ -0,0 +1,254 @@
@extends('layouts.app')
@section('title', '契約者一覧')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">契約者一覧</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item active">契約者一覧</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 絞り込みフィルター --}}
<form method="GET" action="{{ route('contractor') }}" class="mb-3" id="filter-form">
<div class="card p-3">
<h6 class="mb-3">絞り込みフィルター</h6>
<div class="row">
{{-- 左カラム --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">駐輪場</label>
<div class="col-sm-9">
@isset($parks)
<select name="park_id" class="form-control">
<option value="">全て</option>
@foreach($parks as $p)
<option value="{{ $p->park_id }}"
{{ (string)request('park_id')===(string)$p->park_id ? 'selected' : '' }}>
{{ $p->park_name }}
</option>
@endforeach
</select>
@else
<input type="text" name="park_name" value="{{ request('park_name') }}" class="form-control">
@endisset
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者ID</label>
<div class="col-sm-9">
<input type="text" name="user_id" value="{{ request('user_id') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者分類</label>
<div class="col-sm-9">
<input type="text" name="user_categoryid" value="{{ request('user_categoryid') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグシリアル64進</label>
<div class="col-sm-9">
<input type="text" name="user_tag_serial_64" value="{{ request('user_tag_serial_64') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">有効期限</label>
<div class="col-sm-9">
<input type="date" name="contract_periode" value="{{ request('contract_periode') }}" class="form-control">
</div>
</div>
</div>
{{-- 右カラム --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">フリガナ</label>
<div class="col-sm-9">
<input type="text" name="user_phonetic" value="{{ request('user_phonetic') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">電話番号</label>
<div class="col-sm-9">
<input type="text" name="user_mobile" value="{{ request('user_mobile') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">メールアドレス</label>
<div class="col-sm-9">
<input type="text" name="user_primemail" value="{{ request('user_primemail') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">勤務先</label>
<div class="col-sm-9">
<input type="text" name="user_workplace" value="{{ request('user_workplace') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">学校</label>
<div class="col-sm-9">
<input type="text" name="user_school" value="{{ request('user_school') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグ・QR</label>
<div class="col-sm-9">
<select name="tag_qr_flag" class="form-control">
<option value="" {{ request('tag_qr_flag')==='' ? 'selected' : '' }}>全て</option>
<option value="1" {{ request('tag_qr_flag')==='1' ? 'selected' : '' }}>QR</option>
<option value="0" {{ request('tag_qr_flag')==='0' ? 'selected' : '' }}>タグ</option>
</select>
</div>
</div>
</div>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-default">絞り込み</button>
<a href="{{ route('contractor') }}" class="btn btn-default">解除</a>
</div>
</div>
</form>
{{-- 一覧テーブル --}}
<div class="table-responsive">
<table class="table table-bordered table-hover table-sm rv-table text-nowrap">
<thead>
<tr>
<th>利用者ID</th>
<th>氏名</th>
<th>フリガナ</th>
<th>
<a href="{{ request()->fullUrlWithQuery([
'sort' => 'rc.contract_id',
'sort_type' => (request('sort') === 'rc.contract_id' && request('sort_type') === 'asc') ? 'desc' : 'asc'
]) }}">
定期契約ID
@if(request('sort') === 'rc.contract_id')
@if(request('sort_type') === 'asc')
@else
@endif
@endif
</a>
</th>
<th>タグ・QR</th>
<th>駐輪場</th>
<th>車種区分</th>
<th>減免措置</th>
<th>利用者分類1</th>
<th>利用者分類2</th>
<th>利用者分類3</th>
<th>携帯電話番号</th>
<th>自宅電話番号</th>
<th>生年月日</th>
<th>性別</th>
<th>居住所:郵便番号</th>
<th>居住所:都道府県</th>
<th>居住所:市区群</th>
<th>居住所:住所</th>
<th>関連住所:郵便番号</th>
<th>関連住所:都道府県</th>
<th>関連住所:市区群</th>
<th>関連住所:住所</th>
<th>契約日</th>
<th>利用期間</th>
<th>有効期間</th>
<th>定期券区分</th>
<th>勤務先名</th>
<th>学校</th>
<th>卒業予定</th>
<th>シール発行回数</th>
<th>防犯登録</th>
<th>備考</th>
</tr>
</thead>
<tbody>
@forelse ($rows as $row)
<tr>
<td>{{ $row->user_id }}</td>
<td>{{ $row->user_name }}</td>
<td>{{ $row->user_phonetic }}</td>
<td>{{ $row->contract_id }}</td>
<td>{{ $row->tag_qr_flag ? 'QR' : 'タグ' }}</td>
<td>{{ $row->park_name }}</td>
<td>{{ $row->vehicle_type ?? '' }}</td>
<td>{{ $row->user_reduction ?? '' }}</td>
<td>{{ $row->user_category1 ?? '' }}</td>
<td>{{ $row->user_category2 ?? '' }}</td>
<td>{{ $row->user_category3 ?? '' }}</td>
<td>{{ $row->user_mobile }}</td>
<td>{{ $row->user_homephone }}</td>
<td>{{ $row->user_birthdate }}</td>
<td>{{ $row->user_gender }}</td>
<td>{{ $row->user_regident_zip }}</td>
<td>{{ $row->user_regident_pre }}</td>
<td>{{ $row->user_regident_city }}</td>
<td>{{ $row->user_regident_add }}</td>
<td>{{ $row->user_relate_zip }}</td>
<td>{{ $row->user_relate_pre }}</td>
<td>{{ $row->user_relate_city }}</td>
<td>{{ $row->user_relate_add }}</td>
<td>{{ $row->contract_created_at }}</td>
<td>{{ $row->contract_periods }}</td>
<td>{{ $row->contract_periode }}</td>
<td>{{ $row->ticket_type ?? '' }}</td>
<td>{{ $row->user_workplace }}</td>
<td>{{ $row->user_school }}</td>
<td>{{ $row->user_graduate }}</td>
<td>{{ $row->seal_issue_count ?? '' }}</td>
<td>{{ $row->crime_prevention ?? '' }}</td>
<td>{{ $row->user_remarks }}</td>
</tr>
@empty
<tr>
<td colspan="33" class="text-center">データがありません。</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-3">
{{ $rows->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
</div>
</section>
{{-- 画面用スタイル(表頭をグレー、データ部分を白) --}}
<style>
.rv-table thead th{
background:#eeeeee;
white-space:nowrap;
vertical-align:middle;
}
.rv-table tbody tr {
background: #fff;
}
</style>
@endsection

View File

@ -0,0 +1,254 @@
@extends('layouts.app')
@section('title', '未更新者一覧')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">未更新者一覧</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item active">未更新者一覧</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 絞り込みフィルター --}}
<form method="GET" action="{{ route('contractor') }}" class="mb-3" id="filter-form">
<div class="card p-3">
<h6 class="mb-3">絞り込みフィルター</h6>
<div class="row">
{{-- 左カラム --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">駐輪場</label>
<div class="col-sm-9">
@isset($parks)
<select name="park_id" class="form-control">
<option value="">全て</option>
@foreach($parks as $p)
<option value="{{ $p->park_id }}"
{{ (string)request('park_id')===(string)$p->park_id ? 'selected' : '' }}>
{{ $p->park_name }}
</option>
@endforeach
</select>
@else
<input type="text" name="park_name" value="{{ request('park_name') }}" class="form-control">
@endisset
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者ID</label>
<div class="col-sm-9">
<input type="text" name="user_id" value="{{ request('user_id') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者分類</label>
<div class="col-sm-9">
<input type="text" name="user_categoryid" value="{{ request('user_categoryid') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグシリアル64進</label>
<div class="col-sm-9">
<input type="text" name="user_tag_serial_64" value="{{ request('user_tag_serial_64') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">有効期限</label>
<div class="col-sm-9">
<input type="date" name="contract_periode" value="{{ request('contract_periode') }}" class="form-control">
</div>
</div>
</div>
{{-- 右カラム --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">フリガナ</label>
<div class="col-sm-9">
<input type="text" name="user_phonetic" value="{{ request('user_phonetic') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">電話番号</label>
<div class="col-sm-9">
<input type="text" name="user_mobile" value="{{ request('user_mobile') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">メールアドレス</label>
<div class="col-sm-9">
<input type="text" name="user_primemail" value="{{ request('user_primemail') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">勤務先</label>
<div class="col-sm-9">
<input type="text" name="user_workplace" value="{{ request('user_workplace') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">学校</label>
<div class="col-sm-9">
<input type="text" name="user_school" value="{{ request('user_school') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグ・QR</label>
<div class="col-sm-9">
<select name="tag_qr_flag" class="form-control">
<option value="" {{ request('tag_qr_flag')==='' ? 'selected' : '' }}>全て</option>
<option value="1" {{ request('tag_qr_flag')==='1' ? 'selected' : '' }}>QR</option>
<option value="0" {{ request('tag_qr_flag')==='0' ? 'selected' : '' }}>タグ</option>
</select>
</div>
</div>
</div>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-default">絞り込み</button>
<a href="{{ route('contractor') }}" class="btn btn-default">解除</a>
</div>
</div>
</form>
{{-- 一覧テーブル --}}
<div class="table-responsive">
<table class="table table-bordered table-hover table-sm rv-table text-nowrap">
<thead>
<tr>
<th>利用者ID</th>
<th>氏名</th>
<th>フリガナ</th>
<th>
<a href="{{ request()->fullUrlWithQuery([
'sort' => 'contract_id',
'sort_type' => (request('sort') === 'contract_id' && request('sort_type') === 'asc') ? 'desc' : 'asc'
]) }}">
定期契約ID
@if(request('sort') === 'contract_id')
@if(request('sort_type') === 'asc')
@else
@endif
@endif
</a>
</th>
<th>タグ・QR</th>
<th>駐輪場</th>
<th>車種区分</th>
<th>減免措置</th>
<th>利用者分類1</th>
<th>利用者分類2</th>
<th>利用者分類3</th>
<th>携帯電話番号</th>
<th>自宅電話番号</th>
<th>生年月日</th>
<th>性別</th>
<th>居住所:郵便番号</th>
<th>居住所:都道府県</th>
<th>居住所:市区群</th>
<th>居住所:住所</th>
<th>関連住所:郵便番号</th>
<th>関連住所:都道府県</th>
<th>関連住所:市区群</th>
<th>関連住所:住所</th>
<th>契約日</th>
<th>利用期間</th>
<th>有効期間</th>
<th>定期券区分</th>
<th>勤務先名</th>
<th>学校</th>
<th>卒業予定</th>
<th>シール発行回数</th>
<th>防犯登録</th>
<th>備考</th>
</tr>
</thead>
<tbody>
@forelse ($rows as $row)
<tr>
<td>{{ $row->user_id }}</td>
<td>{{ $row->user_name }}</td>
<td>{{ $row->user_phonetic }}</td>
<td>{{ $row->contract_id }}</td>
<td>{{ $row->tag_qr_flag ? 'QR' : 'タグ' }}</td>
<td>{{ $row->park_name }}</td>
<td>{{ $row->vehicle_type ?? '' }}</td>
<td>{{ $row->user_reduction ?? '' }}</td>
<td>{{ $row->user_category1 ?? '' }}</td>
<td>{{ $row->user_category2 ?? '' }}</td>
<td>{{ $row->user_category3 ?? '' }}</td>
<td>{{ $row->user_mobile }}</td>
<td>{{ $row->user_homephone }}</td>
<td>{{ $row->user_birthdate }}</td>
<td>{{ $row->user_gender }}</td>
<td>{{ $row->user_regident_zip }}</td>
<td>{{ $row->user_regident_pre }}</td>
<td>{{ $row->user_regident_city }}</td>
<td>{{ $row->user_regident_add }}</td>
<td>{{ $row->user_relate_zip }}</td>
<td>{{ $row->user_relate_pre }}</td>
<td>{{ $row->user_relate_city }}</td>
<td>{{ $row->user_relate_add }}</td>
<td>{{ $row->contract_created_at }}</td>
<td>{{ $row->contract_periods }}</td>
<td>{{ $row->contract_periode }}</td>
<td>{{ $row->ticket_type ?? '' }}</td>
<td>{{ $row->user_workplace }}</td>
<td>{{ $row->user_school }}</td>
<td>{{ $row->user_graduate }}</td>
<td>{{ $row->seal_issue_count ?? '' }}</td>
<td>{{ $row->crime_prevention ?? '' }}</td>
<td>{{ $row->user_remarks }}</td>
</tr>
@empty
<tr>
<td colspan="33" class="text-center">データがありません。</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-3">
{{ $rows->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
</div>
</section>
{{-- 画面用スタイル(表頭をグレー、データ部分を白) --}}
<style>
.rv-table thead th{
background:#eeeeee;
white-space:nowrap;
vertical-align:middle;
}
.rv-table tbody tr {
background: #fff;
}
</style>
@endsection

View File

@ -0,0 +1,24 @@
<div class="form-group">
<label for="city_id">市区ID</label>
<input type="text" name="city_id" id="city_id" class="form-control" value="{{ old('city_id', $city->city_id ?? '') }}" readonly>
</div>
<div class="form-group">
<label for="city_name">市区名</label>
<input type="text" name="city_name" id="city_name" class="form-control" value="{{ old('city_name', $city->city_name ?? '') }}" required>
</div>
<div class="form-group">
<label for="print_layout">印字レイアウトファイル</label>
<input type="text" name="print_layout" id="print_layout" class="form-control" value="{{ old('print_layout', $city->print_layout ?? '') }}">
</div>
<div class="form-group">
<label for="city_user">顧客M入力不要フィールドID</label>
<input type="text" name="city_user" id="city_user" class="form-control" value="{{ old('city_user', $city->city_user ?? '') }}">
</div>
<div class="form-group">
<label for="city_remarks">備考</label>
<textarea name="city_remarks" id="city_remarks" class="form-control" rows="3">{{ old('city_remarks', $city->city_remarks ?? '') }}</textarea>
</div>

View File

@ -0,0 +1,73 @@
@extends('layouts.app')
@section('title', 'ニュース新規作成')
@section('content')
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">ニュース新規作成</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('news') }}">最新ニュース登録</a></li>
<li class="breadcrumb-item active">新規作成</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- バリデーションエラー表示 --}}
@if ($errors->any())
<div class="alert alert-danger"><ul class="mb-0">@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul></div>
@endif
{{-- 入力フォーム --}}
<div class="card">
<div class="card-body">
<form method="post" action="{{ route('news_add') }}">
@csrf
<div class="form-group">
<label>ニュース内容 <span class="text-danger">*</span></label>
<textarea name="news" class="form-control" rows="8" required>{{ old('news') }}</textarea>
</div>
<div class="form-group">
<label>公開日時2025-08-13 09:00:00</label>
<input type="text" name="open_datetime" class="form-control" placeholder="YYYY-MM-DD HH:MM:SS" value="{{ old('open_datetime') }}">
</div>
<div class="form-group">
<label>リンクURL</label>
<input type="text" name="link_url" class="form-control" value="{{ old('link_url') }}">
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>画像1URL</label>
<input type="text" name="image1_filename" class="form-control" value="{{ old('image1_filename') }}">
</div>
<div class="form-group col-md-6">
<label>画像2URL</label>
<input type="text" name="image2_filename" class="form-control" value="{{ old('image2_filename') }}">
</div>
</div>
<div class="form-group">
<label>表示モード <span class="text-danger">*</span></label>
<select name="mode" class="form-control" required>
<option value="1" @selected(old('mode','1')=='1')>公開</option>
<option value="2" @selected(old('mode')=='2')>下書き</option>
<option value="0" @selected(old('mode')=='0')>非表示</option>
</select>
</div>
<div class="text-right">
<a href="{{ route('news') }}" class="btn btn-outline-secondary">戻る</a>
<button class="btn btn-primary">登録</button>
</div>
</form>
</div>
</div>
</div>
</section>
@endsection

View File

@ -0,0 +1,81 @@
@extends('layouts.app')
@section('title', 'ニュース編集')
@section('content')
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">ニュース編集</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('news') }}">最新ニュース登録</a></li>
<li class="breadcrumb-item active">編集</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- フラッシュ/エラー表示 --}}
@if(session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif
@if ($errors->any())
<div class="alert alert-danger"><ul class="mb-0">@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul></div>
@endif
{{-- 入力フォーム --}}
<div class="card">
<div class="card-body">
<form method="post" action="{{ route('news_edit', ['id'=>$news->news_id ?? $news->id]) }}">
@csrf
<div class="form-group">
<label>ニュース内容 <span class="text-danger">*</span></label>
<textarea name="news" class="form-control" rows="8" required>{{ old('news', $news->news) }}</textarea>
</div>
<div class="form-group">
<label>公開日時</label>
<input type="text" name="open_datetime" class="form-control" placeholder="YYYY-MM-DD HH:MM:SS"
value="{{ old('open_datetime', $news->open_datetime) }}">
</div>
<div class="form-group">
<label>リンクURL</label>
<input type="text" name="link_url" class="form-control" value="{{ old('link_url', $news->link_url) }}">
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>画像1URL</label>
<input type="text" name="image1_filename" class="form-control" value="{{ old('image1_filename', $news->image1_filename) }}">
</div>
<div class="form-group col-md-6">
<label>画像2URL</label>
<input type="text" name="image2_filename" class="form-control" value="{{ old('image2_filename', $news->image2_filename) }}">
</div>
</div>
<div class="form-group">
<label>表示モード <span class="text-danger">*</span></label>
<select name="mode" class="form-control" required>
<option value="1" @selected(old('mode', $news->mode)==1)>公開</option>
<option value="2" @selected(old('mode', $news->mode)==2)>下書き</option>
<option value="0" @selected(old('mode', $news->mode)==0)>非表示</option>
</select>
</div>
<div class="text-right">
<a href="{{ route('news') }}" class="btn btn-outline-secondary">一覧に戻る</a>
<button class="btn btn-primary">保存</button>
</div>
</form>
</div>
</div>
{{-- 登録/更新メタ情報 --}}
<div class="text-muted small">
<div>登録日時:{{ $news->created_at }}</div>
<div>更新日時:{{ $news->updated_at }}</div>
</div>
</div>
</section>
@endsection

View File

@ -0,0 +1,59 @@
@extends('layouts.app')
@section('title', 'ニュース詳細')
@section('content')
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">ニュース詳細</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('news') }}">最新ニュース登録</a></li>
<li class="breadcrumb-item active">詳細</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 詳細表示 --}}
<div class="card">
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">ニュースID</dt><dd class="col-sm-9">{{ $news->id }}</dd>
<dt class="col-sm-3">ニュース内容</dt><dd class="col-sm-9"><pre class="mb-0" style="white-space:pre-wrap;">{{ $news->news }}</pre></dd>
<dt class="col-sm-3">公開日時</dt><dd class="col-sm-9">{{ $news->open_datetime }}</dd>
<dt class="col-sm-3">リンクURL</dt><dd class="col-sm-9">{{ $news->link_url }}</dd>
<dt class="col-sm-3">画像1URL</dt><dd class="col-sm-9">{{ $news->image1_filename }}</dd>
<dt class="col-sm-3">画像2URL</dt><dd class="col-sm-9">{{ $news->image2_filename }}</dd>
<dt class="col-sm-3">表示モード</dt>
<dd class="col-sm-9">
@php $modeLabel = [0=>'非表示',1=>'公開',2=>'下書き']; @endphp
<span class="badge {{ $news->mode==1?'badge-success':($news->mode==2?'badge-warning':'badge-secondary') }}">
{{ $modeLabel[$news->mode] ?? $news->mode }}
</span>
</dd>
<dt class="col-sm-3">登録日時</dt><dd class="col-sm-9">{{ $news->created_at }}</dd>
<dt class="col-sm-3">更新日時</dt><dd class="col-sm-9">{{ $news->updated_at }}</dd>
<dt class="col-sm-3">オペレーターID</dt><dd class="col-sm-9">{{ $news->operator_id }}</dd>
</dl>
{{-- 操作ボタン --}}
<div class="text-right">
<a href="{{ route('news_edit', ['id'=>$news->id]) }}" class="btn btn-primary">編集</a>
<form method="post" action="{{ route('news_delete') }}" class="d-inline" onsubmit="return confirm('削除しますか?')">
@csrf
<input type="hidden" name="id" value="{{ $news->id }}">
<button class="btn btn-outline-danger">削除</button>
</form>
<a href="{{ route('news') }}" class="btn btn-outline-secondary">一覧に戻る</a>
</div>
</div>
</div>
</div>
</section>
@endsection

View File

@ -0,0 +1,120 @@
@extends('layouts.app')
@section('title', '最新ニュース登録')
@section('content')
@php
// ▼ 表示モードのラベル
$modeLabel = [0=>'非表示', 1=>'公開', 2=>'下書き', 3=>'自動公開'];
@endphp
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">最新ニュース登録</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item active">最新ニュース登録</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- フラッシュメッセージ --}}
@if(session('success')) <div class="alert alert-success">{{ session('success') }}</div> @endif
@if(session('error')) <div class="alert alert-danger">{{ session('error') }}</div> @endif
<div class="card">
{{-- ヘッダー:新規/削除 --}}
<div class="card-header d-flex align-items-center">
<a href="{{ route('news_add') }}" class="btn btn-primary mr-2">新規</a>
<button form="news-list-form" type="submit" class="btn btn-outline-secondary"
onclick="return confirm('選択した項目を削除しますか?')">削除</button>
</div>
{{-- 一覧テーブル --}}
<div class="card-body p-0">
<form id="news-list-form" method="POST" action="{{ route('news_delete') }}">
@csrf
<div class="table-responsive">
<table class="table table-bordered text-nowrap mb-0 table-news"> {{-- table-striped は使わない --}}
<thead class="thead-light">
<tr>
{{-- 統合列:ヘッダーも同色 --}}
<th class="col-actions">
<div class="actions-wrap">
<input type="checkbox" id="check-all">
<span class="text-muted" style="font-weight:normal;"></span>
</div>
</th>
{{-- データ列 --}}
<th class="w-id">ニュースID</th>
<th>ニュース内容</th>
<th class="w-datetime">公開日時</th>
<th class="w-url">リンクURL</th>
<th class="w-img">画像1URL</th>
<th class="w-img">画像2URL</th>
<th class="w-mode">表示モード</th>
<th class="w-created">登録日時</th>
<th class="w-updated">更新日時</th>
</tr>
</thead>
<tbody>
@forelse($rows as $r)
<tr>
{{-- 統合セル--}}
<td style="background: #faebd7;">
<div class="actions-wrap">
<input type="checkbox" name="ids[]" value="{{ $r->id }}">
<a href="{{ route('news_edit', ['id' => $r->id]) }}"
class="btn btn-sm btn-outline-primary ml-2">編集</a>
</div>
</td>
{{-- データ本体 --}}
<td class="w-id">{{ $r->id }}</td>
<td class="one-line" title="{{ $r->news }}">{{ \Illuminate\Support\Str::limit($r->news, 80) }}</td>
<td class="w-datetime">{{ $r->open_datetime }}</td>
<td class="w-url one-line" title="{{ $r->link_url }}">{{ $r->link_url }}</td>
<td class="w-img one-line" title="{{ $r->image1_filename }}">{{ $r->image1_filename }}</td>
<td class="w-img one-line" title="{{ $r->image2_filename }}">{{ $r->image2_filename }}</td>
<td class="w-mode">{{ $modeLabel[$r->mode] ?? $r->mode }}</td>
<td class="w-created">{{ $r->created_at }}</td>
<td class="w-updated">{{ $r->updated_at }}</td>
</tr>
@empty
<tr>
<td colspan="10" class="text-center text-muted">データがありません。</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- フッター:ページネーション右寄せ --}}
<div class="d-flex align-items-center p-3">
<div class="ml-auto">
{{ $rows->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
</div>
</form>
</div>
</div>
</div>
</section>
{{-- スクリプト:全選択/全解除 --}}
<script>
document.getElementById('check-all')?.addEventListener('change', function(e){
document.querySelectorAll('input[name="ids[]"]').forEach(function(el){
el.checked = e.target.checked;
});
});
</script>
@endsection

View File

@ -0,0 +1,62 @@
@extends('layouts.app')
@section('title', '区画別利用状況')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">区画別利用状況</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item active">区画別利用状況</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
<div class="card">
<div class="card-body">
<table id="area-table" class="table table-bordered table-striped">
<thead>
<tr>
<th>区画名</th>
<th>駐輪場名</th>
<th>市区名</th>
<th>利用数</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</section>
@push('scripts')
<script>
$(function () {
$('#area-table').DataTable({
processing: true,
serverSide: false,
ajax: {
url: "{{ route('periodical.areaListData') }}",
dataSrc: 'data'
},
columns: [
{ data: 'area_name' },
{ data: 'parking_name' },
{ data: 'city_name' },
{ data: 'usage_count' }
]
});
});
</script>
@endpush
@endsection

View File

@ -0,0 +1,226 @@
@extends('layouts.app')
@section('title', '定期利用・契約状況')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">定期利用・契約状況</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item active">定期利用・契約状況</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 検索条件 --}}
<div class="card mb-3">
<div class="card-body">
<form id="filter-form" class="form-inline" onsubmit="return false;">
<label class="mr-2">駐輪場:</label>
<select name="park_id" id="park_id" class="form-control mr-3">
<option value="">全て</option>
@foreach($parks as $pk)
<option value="{{ $pk->park_id }}" {{ (string) $pk->park_id === (string) ($selectedParkId ?? '') ? 'selected' : '' }}>
{{ $pk->park_name }}
</option>
@endforeach
</select>
</form>
<small class="text-muted d-block mt-2">以下に記載以外の期間情報を参照したい場合は、マスタ管理>定期期間マスタ のCSV出力を利用してください。</small>
</div>
</div>
{{-- 契約状況 --}}
<div class="card mb-4">
<div class="card-header bg-light">
<strong>契約状況</strong>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered mb-0 text-center">
<thead>
<tr>
<th rowspan="2" class="align-middle">契約状況</th>
<th colspan="2">一般</th>
<th colspan="2">学生</th>
<th rowspan="2" class="align-middle">利用計</th>
<th rowspan="2" class="align-middle">空き</th>
<th rowspan="2" class="align-middle">合計</th>
<th colspan="2">直近契約</th>
</tr>
<tr>
<th>件数</th>
<th><!-- 予備 --></th>
<th>件数</th>
<th><!-- 予備 --></th>
<th>予約日</th>
<th>契約日</th>
</tr>
</thead>
<tbody id="tbl-contract-summary"></tbody>
</table>
</div>
</div>
</div>
{{-- 空き待ち状況 --}}
<div class="card mb-4">
<div class="card-header bg-light">
<strong>空き待ち状況</strong>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered mb-0 text-center">
<thead>
<tr>
<th rowspan="2" class="align-middle">空き待ち状況</th>
<th colspan="2">一般</th>
<th colspan="2">学生</th>
<th rowspan="2" class="align-middle">合計</th>
</tr>
<tr>
<th>件数</th>
<th>先頭日</th>
<th>件数</th>
<th>先頭日</th>
</tr>
</thead>
<tbody id="tbl-waiting-summary"></tbody>
</table>
</div>
</div>
</div>
{{-- 更新状況 --}}
<div class="card mb-4">
<div class="card-header bg-light">
<strong>更新状況</strong>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered mb-0 text-center">
<thead>
<tr>
<th rowspan="2" class="align-middle" style="min-width:70px"></th>
<th colspan="3">自転車</th>
<th colspan="3">原付</th>
<th colspan="3">その他</th>
</tr>
<tr>
<th>一般</th>
<th>学生</th>
<th></th>
<th>一般</th>
<th>学生</th>
<th></th>
<th>一般</th>
<th>学生</th>
<th></th>
</tr>
</thead>
<tbody id="tbl-renewal-summary"></tbody>
</table>
</div>
</div>
</div>
</div>
</section>
@push('scripts')
<script>
$(function () {
loadStats();
$('#park_id').on('change', function () {
loadStats();
});
function loadStats() {
$.ajax({
url: "{{ route('periodical.listData') }}",
type: 'GET',
data: { park_id: $('#park_id').val() },
success: function (res) {
renderContractSummary(res.contract_summary || []);
renderWaitingSummary(res.waiting_summary || []);
renderRenewalSummary(res.renewal_summary || []);
},
error: function (xhr) {
console.error(xhr.responseText || xhr.statusText);
}
});
}
function nz(v) { return (v === null || v === undefined || v === '') ? '' : v; }
function renderContractSummary(rows) {
const $tb = $('#tbl-contract-summary').empty();
rows.forEach(r => {
$tb.append(`
<tr>
<td class="text-left">${r.type}</td>
<td>${nz(r.general_count)}</td>
<td>${nz(r.general_extra)}</td>
<td>${nz(r.student_count)}</td>
<td>${nz(r.student_extra)}</td>
<td>${nz(r.use_total)}</td>
<td>${nz(r.vacancy)}</td>
<td>${nz(r.total)}</td>
<td>${r.last && r.last.reserve_date ? r.last.reserve_date : ''}</td>
<td>${r.last && r.last.contract_date ? r.last.contract_date : ''}</td>
</tr>
`);
});
}
function renderWaitingSummary(rows) {
const $tb = $('#tbl-waiting-summary').empty();
rows.forEach(r => {
$tb.append(`
<tr>
<td class="text-left">${r.type}</td>
<td>${nz(r.general_count)}</td>
<td>${nz(r.general_head)}</td>
<td>${nz(r.student_count)}</td>
<td>${nz(r.student_head)}</td>
<td>${nz(r.total)}</td>
</tr>
`);
});
}
function renderRenewalSummary(rows) {
const $tb = $('#tbl-renewal-summary').empty();
rows.forEach(r => {
$tb.append(`
<tr>
<td class="text-left">${r.month}</td>
<td>${nz(r.bicycle_general)}</td>
<td>${nz(r.bicycle_student)}</td>
<td>${nz(r.bicycle_total)}</td>
<td>${nz(r.moped_general)}</td>
<td>${nz(r.moped_student)}</td>
<td>${nz(r.moped_total)}</td>
<td>${nz(r.others_general)}</td>
<td>${nz(r.others_student)}</td>
<td>${nz(r.others_total)}</td>
</tr>
`);
});
}
});
</script>
@endpush
@endsection

View File

@ -0,0 +1,172 @@
{{-- 駐輪場マスタ 共通フォーム --}}
<form method="POST" action="" enctype="multipart/form-data">
@csrf
{{-- 駐輪場ID --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">駐輪場ID</label>
<div class="col-md-4">
<input type="text" name="park_id" value="{{ $park_id ?? '' }}" class="form-control" readonly>
</div>
</div>
{{-- 市区 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">市区 <span class="text-danger">*</span></label>
<div class="col-md-4">
<select class="form-control" name="city_id" @if($isInfo) disabled @endif>
<option value="">市区を選択</option>
@foreach($cities as $city)
<option value="{{ $city->city_id }}" @if(old('city_id', $city_id ?? '') == $city->city_id) selected @endif>
{{ $city->city_name }}
</option>
@endforeach
</select>
</div>
</div>
{{-- 駐輪場名 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">駐輪場名 <span class="text-danger">*</span></label>
<div class="col-md-4">
<input type="text" name="park_name" value="{{ old('park_name', $park_name ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 駐輪場ふりがな --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">駐輪場ふりがな</label>
<div class="col-md-4">
<input type="text" name="park_ruby" value="{{ old('park_ruby', $park_ruby ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 駐輪場五十音 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">駐輪場五十音</label>
<div class="col-md-4">
<input type="text" name="park_syllabary" value="{{ old('park_syllabary', $park_syllabary ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 住所 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">住所</label>
<div class="col-md-6">
<input type="text" name="park_adrs" value="{{ old('park_adrs', $park_adrs ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 閉設フラグ --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">閉設フラグ</label>
<div class="col-md-6 d-flex align-items-center">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="park_close_flag" id="open" value="0" {{ (old('park_close_flag', $park_close_flag ?? 0) == 0) ? 'checked' : '' }} @if($isInfo) disabled @endif>
<label class="form-check-label" for="open">開設</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="park_close_flag" id="close" value="1" {{ (old('park_close_flag', $park_close_flag ?? 0) == 1) ? 'checked' : '' }} @if($isInfo) disabled @endif>
<label class="form-check-label" for="close">閉設</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="park_close_flag" id="prep" value="2" {{ (old('park_close_flag', $park_close_flag ?? 0) == 2) ? 'checked' : '' }} @if($isInfo) disabled @endif>
<label class="form-check-label" for="prep">準備中</label>
</div>
</div>
</div>
{{-- 閉設日 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">閉設日</label>
<div class="col-md-4">
<input type="date" name="park_day" value="{{ old('park_day', $park_day ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 残警告チェックフラグ --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">残警告チェックフラグ</label>
<div class="col-md-4">
<input type="text" name="alert_flag" value="{{ old('alert_flag', $alert_flag ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 印字数 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">印字数</label>
<div class="col-md-4">
<input type="text" name="print_number" value="{{ old('print_number', $print_number ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- 最新キープアライブ --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">最新キープアライブ</label>
<div class="col-md-4">
<input type="datetime-local" name="keep_alive" value="{{ !empty($keep_alive) ? date('Y-m-d\TH:i', strtotime($keep_alive)) : '' }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
{{-- ---- 以下为未来扩展的字段,请用时补充数据库和控制器变量,并去掉注释 ---- --}}
{{--
<div class="form-group row">
<label class="col-md-2 col-form-label">料金メモ</label>
<div class="col-md-8">
<input type="text" name="price_memo" value="{{ old('price_memo', $price_memo ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label">更新期間開始日</label>
<div class="col-md-4">
<input type="date" name="update_start_date" value="{{ old('update_start_date', $update_start_date ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
<label class="col-md-2 col-form-label">更新期間開始時</label>
<div class="col-md-4">
<input type="time" name="update_start_time" value="{{ old('update_start_time', $update_start_time ?? '') }}" class="form-control" @if($isInfo) readonly @endif>
</div>
</div>
<div class="form-group row">
<label class="col-md-2 col-form-label">契約後即利用許可</label>
<div class="col-md-4">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="can_use_after_contract" value="1" @if(old('can_use_after_contract', $can_use_after_contract ?? '') == 1) checked @endif @if($isInfo) disabled @endif>
<label class="form-check-label">許可する</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="can_use_after_contract" value="0" @if(old('can_use_after_contract', $can_use_after_contract ?? '') == 0) checked @endif @if($isInfo) disabled @endif>
<label class="form-check-label">許可しない</label>
</div>
</div>
</div>
--}}
{{-- 備考 --}}
<div class="form-group row">
<label class="col-md-2 col-form-label">備考</label>
<div class="col-md-8">
<textarea name="note" class="form-control" rows="2" @if($isInfo) readonly @endif>{{ old('note', $note ?? '') }}</textarea>
</div>
</div>
{{-- ここから他のフィールドも同様に追加 --}}
{{-- ... --}}
{{-- 图片上传字段样例 --}}
{{--
<div class="form-group row">
<label class="col-md-2 col-form-label">駐輪場画像1</label>
<div class="col-md-4">
<input type="file" name="parking_image1" class="form-control-file" @if($isInfo) disabled @endif>
@if(!empty($parking_image1_url))
<img src="{{ $parking_image1_url }}" alt="駐輪場画像1" class="img-thumbnail mt-2" style="max-width:200px;">
@endif
</div>
</div>
--}}
</form>

View File

@ -0,0 +1,48 @@
@extends('layouts.app')
@section('title', '車種区分新規登録')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">車種区分新規登録</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('psection') }}">車種区分マスタ</a></li>
<li class="breadcrumb-item active">新規</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 显示错误信息 --}}
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('psection_add') }}">
@csrf
<div class="form-group">
<label>車種区分ID <span class="text-danger">*</span></label>
<input type="number" name="psection_id" class="form-control" value="{{ old('psection_id') }}" required>
</div>
<div class="form-group">
<label>車種区分名 <span class="text-danger">*</span></label>
<input type="text" name="psection_subject" class="form-control" value="{{ old('psection_subject') }}" required>
</div>
<button type="submit" class="btn btn-primary"
onclick="return confirm('保存してもよろしいですか?');">登録</button>
<a href="{{ route('psection') }}" class="btn btn-secondary">戻る</a>
</form>
</div>
</section>
@endsection

View File

@ -0,0 +1,35 @@
@extends('layouts.app')
@section('title', '車種区分新規登録')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">車種区分新規登録</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('psection') }}">車種区分マスタ</a></li>
<li class="breadcrumb-item active">新規</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
<form method="POST" action="{{ route('psection_add') }}">
@csrf
<div class="form-group">
<label>車種区分ID <span class="text-danger">*</span></label>
<input type="number" name="psection_id" class="form-control" value="{{ old('psection_id') }}" required>
</div>
<div class="form-group">
<label>車種区分名 <span class="text-danger">*</span></label>
<input type="text" name="psection_subject" class="form-control" value="{{ old('psection_subject') }}" required>
</div>
<button type="submit" class="btn btn-primary">登録</button>
<a href="{{ route('psection') }}" class="btn btn-secondary">戻る</a>
</form>
</div>
</section>
@endsection

View File

@ -0,0 +1,31 @@
@extends('layouts.app')
@section('title', '車種区分詳細')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">車種区分詳細</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('psection') }}">車種区分マスタ</a></li>
<li class="breadcrumb-item active">詳細</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
<div class="form-group">
<label>車種区分ID</label>
<input type="number" value="{{ $psection->psection_id }}" class="form-control" readonly>
</div>
<div class="form-group">
<label>車種区分名</label>
<input type="text" value="{{ $psection->psection_subject }}" class="form-control" readonly>
</div>
<a href="{{ route('psection') }}" class="btn btn-secondary">一覧に戻る</a>
</div>
</section>
@endsection

View File

@ -0,0 +1,102 @@
@extends('layouts.app')
@section('title', '車種区分マスタ')
@section('content')
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">車種区分マスタ</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item active">車種区分マスタ</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- アクションボタン(市区マスタ準拠) --}}
<div class="mb-3">
<a href="{{ route('psection_add') }}" class="btn btn-sm btn-primary">新規</a>
<button type="submit" form="deleteForm" class="btn btn-sm btn-danger ml-2"
onclick="return confirm('選択した区分を削除しますか?');">削除</button>
</div>
@if ($list->count() > 0)
<form id="deleteForm" method="POST" action="{{ route('psection_delete') }}">
@csrf
<div class="table-responsive">
<table class="table table-bordered table-hover" style="min-width:600px;">
<thead class="thead-light">
<tr>
{{-- 統合列:チェック + 編集(背景色は #faebd7 --}}
<th style="width:140px;">
<input type="checkbox" onclick="$('input[name*=\'pk\']').prop('checked', this.checked);">
<span class="text-muted" style="font-weight:normal;"></span>
</th>
{{-- 表頭ソート対応ID / 名称) --}}
<th style="width:140px; text-align:center;">
<a href="{{ route('psection', ['sort' => 'id', 'direction' => ($sort=='id' && $direction=='asc')?'desc':'asc']) }}"
style="color:inherit; text-decoration:none;">
車種区分ID
@if($sort == 'id')
@if($direction == 'asc')
<span style="font-size:1.0em;">&#9650;</span>
@else
<span style="font-size:1.0em;">&#9660;</span>
@endif
@endif
</a>
</th>
<th style="text-align:center;">
<a href="{{ route('psection', ['sort' => 'subject', 'direction' => ($sort=='subject' && $direction=='asc')?'desc':'asc']) }}"
style="color:inherit; text-decoration:none;">
車種区分名
@if($sort == 'subject')
@if($direction == 'asc')
<span style="font-size:1.0em;">&#9650;</span>
@else
<span style="font-size:1.0em;">&#9660;</span>
@endif
@endif
</a>
</th>
</tr>
</thead>
<tbody>
@foreach ($list as $item)
<tr>
{{-- 統合セル:チェック + 編集(市区マスタの老書式に合わせる) --}}
<td style="background: #faebd7;">
<input type="checkbox" name="pk[]" value="{{ $item->psection_id }}">
<a href="{{ route('psection_edit', ['id' => $item->psection_id]) }}"
class="btn btn-sm btn-outline-primary ml-2">編集</a>
</td>
{{-- データ列 --}}
<td style="text-align:right;">{{ $item->psection_id }}</td>
<td>{{ $item->psection_subject }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</form>
@else
{{-- データ無し表示 --}}
<div class="alert alert-info mt-4">表示するデータがありません。</div>
@endif
</div>
</section>
@endsection

View File

@ -0,0 +1,555 @@
@if(Session::has('success'))
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{{ Session::get('success') }}
</div>
@elseif(Session::has('error'))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-ban"></i> エラー:</h4>
{!! Session::get('error') !!}
</div>
@elseif(isset($errorMsg))
<div class="alert alert-danger alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-ban"></i> エラー:</h4>
{!! $errorMsg !!}
</div>
@endif
<div class="card-header">
@if($isInfo)
<a href="{{route('regular_contract_add')}}" class="btn btn-lg btn-success">登録</a>
<a href="{{route('regular_contract_edit',['id'=>$contract_id])}}" class="btn btn-lg btn-danger">編集</a>
@endIf
</div>
<div class="card-body">
<div class="row">
@if($isEdit || $isInfo)
{{-- 定期契約ID --}}
<div class="form-group col-3">
<label>定期契約ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_id}}"
placeholder="定期契約ID"
class="form-control form-control-lg" readonly/>
</div>
</div>
@endif
{{-- 定期契約QRID --}}
<div class="form-group col-3">
<label @if(!$isInfo) class="required" @endif>定期契約QRID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_qr_id}}"
@if(!$isInfo) placeholder="定期契約QRID" @endif name="contract_qr_id"
class="form-control form-control-lg" @if($isEdit || $isInfo) readonly @endif/>
</div>
</div>
{{-- 利用者ID --}}
<div class="form-group col-3">
<label @if(!$isInfo) class="required" @endif>利用者ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$user_id}}" @if(!$isInfo) placeholder="利用者ID" @endif
name="user_id" class="form-control form-control-lg" @if($isEdit || $isInfo) readonly @endif/>
</div>
</div>
{{-- 利用者分類ID --}}
<div class="form-group col-3">
<label @if(!$isInfo) class="required" @endif>利用者分類ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$user_categoryid}}"
@if(!$isInfo) placeholder="利用者分類ID" @endif name="user_categoryid"
class="form-control form-control-lg" @if($isEdit || $isInfo) readonly @endif/>
</div>
</div>
{{-- 定期予約ID --}}
<div class="form-group col-3">
<label @if(!$isInfo) class="required" @endif>定期予約ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$reserve_id}}" @if(!$isInfo) placeholder="定期予約ID" @endif
name="reserve_id" class="form-control form-control-lg" @if($isEdit || $isInfo) readonly @endif/>
</div>
</div>
{{-- 駐輪場ID --}}
<div class="form-group col-3">
<label @if(!$isInfo) class="required" @endif>駐輪場ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$park_id}}" @if(!$isInfo) placeholder="駐輪場ID" @endif
name="park_id" class="form-control form-control-lg" @if($isEdit || $isInfo) readonly @endif/>
</div>
</div>
{{-- 駐輪場所ID --}}
<div class="form-group col-3">
<label @if(!$isInfo) class="required" @endif>駐輪場所ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$price_parkplaceid}}"
@if(!$isInfo) placeholder="駐輪場所ID" @endif name="price_parkplaceid"
class="form-control form-control-lg" @if($isEdit || $isInfo) readonly @endif/>
</div>
</div>
{{-- 防犯登録番号 --}}
<div class="form-group col-3">
<label>防犯登録番号</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$user_securitynum}}"
@if(!$isInfo) placeholder="防犯登録番号" @endif name="user_securitynum"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 予約日時 --}}
<div class="form-group col-3">
<label>予約日時</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="date" value="@if(!empty($reserve_date)){{date('Y-m-d',strtotime($reserve_date))}}@endif"
@if(!$isInfo) placeholder="予約日時" @endif name="reserve_date"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 予約移行 --}}
<div class="form-group col-3">
<label>予約移行</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-4 offset-1 form-check">
<input type="radio" class="minimal"
name="contract_reserve" @if($isInfo) disabled @endif
value="{{ '予約' }}" {{$contract_reserve == '予約'? 'checked':''}}>
<label class="form-check-label">予約</label>
</div>
<div class="col-2 form-check">
<input type="radio" class="minimal"
name="contract_reserve" @if($isInfo) disabled @endif
value="{{ '予約しない' }}" {{$contract_reserve == '予約しない'? 'checked':''}}>
<label class="form-check-label">予約しない</label>
</div>
</div>
</div>
{{-- 契約日時 --}}
<div class="form-group col-3">
<label>契約日時</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="date" value="@if(!empty($created_at)){{date('Y-m-d',strtotime($created_at))}}@endif"
@if(!$isInfo) placeholder="契約日時" @endif name="created_at"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 更新可能日 --}}
<div class="form-group col-3">
<label>更新可能日</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="date" value="@if(!empty($updated_at)){{date('Y-m-d',strtotime($updated_at))}}@endif"
@if(!$isInfo) placeholder="更新可能日" @endif name="updated_at"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 解約日時 --}}
<div class="form-group col-3">
<label>解約日時</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="date"
value="@if(!empty($contract_cancelday)){{date('Y-m-d',strtotime($contract_cancelday))}}@endif"
@if(!$isInfo) placeholder="解約日時" @endif name="contract_cancelday"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 減免措置 --}}
<div class="form-group col-3">
<label>減免措置</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_reduction}}"
@if(!$isInfo) placeholder="減免措置" @endif name="contract_reduction"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 有効期間S --}}
<div class="form-group col-3">
<label>有効期間S</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_periods}}"
@if(!$isInfo) placeholder="有効期間S" @endif name="contract_periods"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 有効期間E --}}
<div class="form-group col-3">
<label>有効期間E</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_periode}}"
@if(!$isInfo) placeholder="有効期間E" @endif name="contract_periode"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 消費税ID --}}
<div class="form-group col-3">
<label>消費税ID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_taxid}}"
@if(!$isInfo) placeholder="消費税ID" @endif name="contract_taxid"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 請求金額 --}}
<div class="form-group col-3">
<label>請求金額</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$billing_amount}}"
@if(!$isInfo) placeholder="請求金額" @endif name="billing_amount"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 授受日時 --}}
<div class="form-group col-3">
<label>授受日時</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="date" value="@if(!empty($contract_payment_day)){{date('Y-m-d',strtotime($contract_payment_day))}}@endif"
@if(!$isInfo) placeholder="授受日時" @endif name="contract_payment_day"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 授受金額 --}}
<div class="form-group col-3">
<label>授受金額</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_money}}"
@if(!$isInfo) placeholder="授受金額" @endif name="contract_money"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 解約時返戻金 --}}
<div class="form-group col-3">
<label>解約時返戻金</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$refunds}}" @if(!$isInfo) placeholder="解約時返戻金" @endif
name="refunds" class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 返戻金付随情報 --}}
<div class="form-group col-3">
<label>返戻金付随情報</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$refunds_comment}}"
@if(!$isInfo) placeholder="返戻金付随情報" @endif name="refunds_comment"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 返金日 --}}
<div class="form-group col-3">
<label>返金日</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="date" value="@if(!empty($repayment_at)){{date('Y-m-d',strtotime($repayment_at))}}@endif"
@if(!$isInfo) placeholder="返金日" @endif name="repayment_at"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 決済コード --}}
<div class="form-group col-3">
<label>決済コード</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contact_guid}}"
@if(!$isInfo) placeholder="決済コード" @endif name="contact_guid"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 店舗コード --}}
<div class="form-group col-3">
<label>店舗コード</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contact_shop_code}}"
@if(!$isInfo) placeholder="店舗コード" @endif name="contact_shop_code"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 授受種別 --}}
<div class="form-group col-3">
<label>授受種別</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_cvs_class}}"
@if(!$isInfo) placeholder="授受種別" @endif name="contract_cvs_class"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 授受フラグ --}}
<div class="form-group col-3">
<label>授受フラグ</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-2 offset-1 form-check">
<input type="radio" class="minimal" name="contract_flag" @if($isInfo) disabled @endif
value="1" {{$contract_flag? 'checked':''}}>
<label class="form-check-label">はい</label>
</div>
<div class="col-2 form-check">
<input type="radio" class="minimal" name="contract_flag" @if($isInfo) disabled @endif
value="0" {{!$contract_flag? 'checked':''}}>
<label class="form-check-label">いいえ</label>
</div>
</div>
</div>
{{-- 決済トランザクションID --}}
<div class="form-group col-3">
<label>決済トランザクションID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$settlement_transaction_id}}"
@if(!$isInfo) placeholder="決済トランザクションID" @endif
name="settlement_transaction_id"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- シール発行数 --}}
<div class="form-group col-3">
<label>シール発行数</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_seal_issue}}"
@if(!$isInfo) placeholder="シール発行数" @endif name="contract_seal_issue"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- シール再発行リクエスト --}}
<div class="form-group col-3">
<label>シール再発行リクエスト</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-2 offset-1 form-check">
<input type="radio" class="minimal" name="seal_reissue_request" @if($isInfo) disabled @endif
value="1" {{$seal_reissue_request? 'checked':''}}>
<label class="form-check-label">はい</label>
</div>
<div class="col-2 form-check">
<input type="radio" class="minimal" name="seal_reissue_request" @if($isInfo) disabled @endif
value="0" {{!$seal_reissue_request? 'checked':''}}>
<label class="form-check-label">いいえ</label>
</div>
</div>
</div>
{{-- シール発行許可 --}}
<div class="form-group col-3">
<label>シール発行許可</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-3 offset-1 form-check">
<input type="radio" class="minimal" name="contract_permission" @if($isInfo) disabled @endif
value="1" {{$contract_permission? 'checked':''}}>
<label class="form-check-label">発行許可</label>
</div>
<div class="col-4 form-check">
<input type="radio" class="minimal" name="contract_permission" @if($isInfo) disabled @endif
value="0" {{!$contract_permission? 'checked':''}}>
<label class="form-check-label">発行許可しない</label>
</div>
</div>
</div>
{{-- 解約フラグ --}}
<div class="form-group col-3">
<label>解約フラグ</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-2 offset-1 form-check">
<input type="radio" class="minimal" name="contract_cancel_flag" @if($isInfo) disabled @endif
value="1" {{$contract_cancel_flag? 'checked':''}}>
<label class="form-check-label">解約</label>
</div>
<div class="col-3 form-check">
<input type="radio" class="minimal" name="contract_cancel_flag" @if($isInfo) disabled @endif
value="0" {{!$contract_cancel_flag? 'checked':''}}>
<label class="form-check-label">解約しない</label>
</div>
</div>
</div>
{{-- タグ・QR --}}
<div class="form-group col-3">
<label>タグ・QR</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-2 offset-1 form-check">
<input type="radio" class="minimal" name="tag_qr_flag" @if($isInfo) disabled @endif
value="0" {{!$tag_qr_flag? 'checked':''}}>
<label class="form-check-label">タグ</label>
</div>
<div class="col-2 form-check">
<input type="radio" class="minimal" name="tag_qr_flag" @if($isInfo) disabled @endif
value="1" {{$tag_qr_flag? 'checked':''}}>
<label class="form-check-label">QR</label>
</div>
</div>
</div>
{{-- オペレータータグ変更フラグ --}}
<div class="form-group col-3">
<label>オペレータータグ変更フラグ</label>
</div>
<div class="form-group col-9">
<div class="row">
<div class="col-5 offset-1 form-check">
<input type="radio" class="minimal" name="tag_change_flag" @if($isInfo) disabled @endif
value="1" {{$tag_change_flag? 'checked':''}}>
<label class="form-check-label">タグに変更する</label>
</div>
<div class="col-5 form-check">
<input type="radio" class="minimal" name="tag_change_flag" @if($isInfo) disabled @endif
value="0" {{!$tag_change_flag? 'checked':''}}>
<label class="form-check-label">タグに変更しない</label>
</div>
</div>
</div>
{{-- 駐輪位置番号 --}}
<div class="form-group col-3">
<label>駐輪位置番号</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$park_position}}"
@if(!$isInfo) placeholder="駐輪位置番号" @endif name="park_position"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- オペレータID --}}
<div class="form-group col-3">
<label>オペレータID</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$ope_id}}" @if(!$isInfo) placeholder="オペレータID" @endif
name="ope_id" class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 手動通知 --}}
<div class="form-group col-3">
<label>手動通知</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_manual}}"
@if(!$isInfo) placeholder="手動通知" @endif name="contract_manual"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 通知方法 --}}
<div class="form-group col-3">
<label>通知方法</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_notice}}"
@if(!$isInfo) placeholder="通知方法" @endif name="contract_notice"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
{{-- 受付番号 --}}
<div class="form-group col-3">
<label>受付番号</label>
</div>
<div class="form-group col-9">
<div class="input-group">
<input type="text" value="{{$contract_payment_number}}"
@if(!$isInfo) placeholder="受付番号" @endif name="contract_payment_number"
class="form-control form-control-lg" @if($isInfo) readonly @endif/>
</div>
</div>
</div>
@if($isInfo)
<a href="{{route('regular_contract_add')}}" class="btn btn-lg btn-success">登録</a>
<a href="{{route('regular_contract_edit',['id'=>$contract_id])}}" class="btn btn-lg btn-danger">編集</a>
@else
<button type="submit" class="btn btn-lg btn-danger" @if(!$isEdit || !$isInfo) id="register" @endif>保存</button>
@endIf
</div>

View File

@ -0,0 +1,347 @@
{{-- resources/views/admin/regularcontracts/add.blade.php --}}
@extends('layouts.app')
@section('title', '新規|定期契約マスタ')
@section('content')
<style>
.rc-page, .rc-page .card, .rc-page .form-control, .rc-page .custom-select, .rc-page .btn {
font-size: 13px;
line-height: 1.45;
}
.rc-form .row-line{display:flex;align-items:center;margin-bottom:.6rem}
.rc-form .row-line .label{flex:0 0 240px;font-weight:600;white-space:nowrap;margin:0;color:#333}
.rc-form .row-line .input{flex:1 1 auto;min-width:260px}
.rc-form .form-control,.rc-form .custom-select{height:calc(2.0rem + 2px);padding:.25rem .5rem}
.rc-form .inline-range{display:flex;gap:.5rem;align-items:center}
.rc-form .inline-range .tilde{color:#666}
.rc-toolbar{display:flex;justify-content:flex-start;gap:.5rem;margin-bottom:.75rem}
</style>
<div class="rc-page">
<div class="content-header">
<div class="container-fluid">
<div class="d-flex align-items-center justify-content-between mb-2">
<h1 class="m-0 text-dark">新規</h1>
<ol class="breadcrumb float-sm-right text-sm mb-0">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('regularcontracts') }}">定期契約マスタ</a></li>
<li class="breadcrumb-item active">新規</li>
</ol>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 上部:登録ボタン(駐輪場所・料金マスタのトーンに合わせた薄いボタン) --}}
<div class="rc-toolbar">
<button form="rc-add-form" type="submit" class="btn btn-sm btn-default">登録</button>
</div>
<div class="card rc-form">
<div class="card-body">
<form id="rc-add-form" method="post" action="{{ route('regularcontracts_add') }}">
@csrf
{{-- ====== 1段目 ====== --}}
<div class="row">
<div class="col-lg-6">
<div class="row-line">
<p class="label">旧定期契約番号</p>
<div class="input"><input name="old_contract_number" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">定期契約QRID</p>
<div class="input"><input name="contract_qr_id" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">利用者ID</p>
<div class="input"><input name="user_id" class="form-control" type="number" min="0"></div>
</div>
<div class="row-line">
<p class="label">利用者分類ID</p>
<div class="input"><input name="user_categoryid" class="form-control" type="number" min="0"></div>
</div>
<div class="row-line">
<p class="label">定期予約ID</p>
<div class="input"><input name="reserve_id" class="form-control" type="number" min="0"></div>
</div>
<div class="row-line">
<p class="label">駐輪場ID</p>
<div class="input"><input name="park_id" class="form-control" type="number" min="0"></div>
</div>
<div class="row-line">
<p class="label">駐輪場所ID</p>
<div class="input"><input name="price_parkplaceid" class="form-control" type="number" min="0"></div>
</div>
<div class="row-line">
<p class="label">防犯登録番号</p>
<div class="input"><input name="crime_prevention_registration_number" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">予約日時</p>
<div class="input inline-range">
<input name="reserve_date" type="datetime-local" class="form-control">
</div>
</div>
<div class="row-line">
<p class="label">契約日時</p>
<div class="input inline-range">
<input name="contract_created_at" type="datetime-local" class="form-control">
</div>
</div>
<div class="row-line">
<p class="label">更新可能日</p>
<div class="input"><input name="renewable_date" type="date" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">解約日時</p>
<div class="input inline-range">
<input name="contract_cancelday" type="datetime-local" class="form-control">
</div>
</div>
<div class="row-line">
<p class="label">有効期間S</p>
<div class="input"><input name="valid_from" type="date" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">有効期間E</p>
<div class="input"><input name="valid_to" type="date" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">定期有効月数</p>
<div class="input"><input name="enable_months" type="number" min="0" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">シール印刷可能日</p>
<div class="input"><input name="printable_date" type="date" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">請求金額</p>
<div class="input"><input name="billing_amount" type="number" step="1" min="0" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">車室割り当てフラグ</p>
<div class="input">
<select name="assign_flag" class="custom-select">
<option value=""></option>
<option value="1">割当済</option>
<option value="0">未割当</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">授受日時</p>
<div class="input"><input name="receipt_delivery_date" type="datetime-local" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">授受金額</p>
<div class="input"><input name="receipt_delivery_amount" type="number" step="1" min="0" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">授受フラグ</p>
<div class="input">
<select name="receipt_delivery_flag" class="custom-select">
<option value=""></option>
<option value="1"></option>
<option value="0"></option>
</select>
</div>
</div>
</div>
{{-- 右列 --}}
<div class="col-lg-6">
<div class="row-line">
<p class="label">決済トランザクションID</p>
<div class="input"><input name="payment_transaction_id" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">シール発行数</p>
<div class="input"><input name="contract_seal_count" type="number" min="0" class="form-control"></div>
</div>
<div class="row-line">
<p class="label">シール発行リクエスト</p>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="contract_seal_request" value="1" id="seal_req1">
<label class="form-check-label" for="seal_req1">はい</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="contract_seal_request" value="0" id="seal_req0" checked>
<label class="form-check-label" for="seal_req0">いいえ</label>
</div>
</div>
</div>
<div class="row-line">
<p class="label">定期継続フラグ</p>
<div class="input">
<select name="contract_continuing" class="custom-select">
<option value=""></option>
<option value="1">継続</option>
<option value="0">それ以外(新規)</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">シール発行可</p>
<div class="input">
<select name="contract_delivery" class="custom-select">
<option value=""></option>
<option value="1">発行可</option>
<option value="0">発行しない</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">減免フラグ</p>
<div class="input">
<select name="contract_reduction" class="custom-select">
<option value=""></option>
<option value="1">減免</option>
<option value="0">減免しない</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">80MOM以内</p>
<div class="input">
<select name="contract_60flag" class="custom-select">
<option value=""></option>
<option value="1"></option>
<option value="0"></option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">タグQRフラグ</p>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="tag_qr_flag" value="1" id="qr1">
<label class="form-check-label" for="qr1"></label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="tag_qr_flag" value="0" id="qr0" checked>
<label class="form-check-label" for="qr0">タグ</label>
</div>
</div>
</div>
<div class="row-line">
<p class="label">オペレータ名変更フラグ</p>
<div class="input">
<select name="tag_change_flag" class="custom-select">
<option value=""></option>
<option value="1">タグに変更してる</option>
<option value="0">タグに変更していない</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">駐輪位置番号</p>
<div class="input"><input name="park_position" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">手動通知</p>
<div class="input"><input name="contract_manual" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">通知方法</p>
<div class="input"><input name="contract_notice" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">受付番号</p>
<div class="input"><input name="accept_number" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">オペレータID</p>
<div class="input"><input name="ope_id" class="form-control" type="number" min="0"></div>
</div>
<div class="row-line">
<p class="label">シール発行許可</p>
<div class="input">
<select name="contract_permission" class="custom-select">
<option value=""></option>
<option value="1">許可</option>
<option value="0">未許可</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">解約フラグ</p>
<div class="input">
<select name="contract_cancel_flag" class="custom-select">
<option value=""></option>
<option value="1">キャンセル</option>
<option value="0"></option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">収納企業コード</p>
<div class="input"><input name="company_code" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">共有先収納企業コード</p>
<div class="input"><input name="shared_company_code" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">(更新元)契約更新済フラグ</p>
<div class="input">
<select name="update_flag" class="custom-select">
<option value=""></option>
<option value="1">更新済</option>
<option value="0">未更新</option>
</select>
</div>
</div>
<div class="row-line">
<p class="label">車種区分ID</p>
<div class="input"><input name="vehicle_type_id" class="form-control" type="number" min="0"></div>
</div>
{{-- チェック用(検索補助の控え) --}}
<div class="row-line">
<p class="label">チェック用_フリガナ</p>
<div class="input"><input name="user_phonetic" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">チェック用_居住所郵便番号</p>
<div class="input"><input name="user_resident_zip" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">チェック用_携帯電話番号</p>
<div class="input"><input name="user_mobile" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">チェック用_自宅電話番号</p>
<div class="input"><input name="user_homephone" class="form-control" type="text"></div>
</div>
<div class="row-line">
<p class="label">チェック用_旧会員番号</p>
<div class="input"><input name="old_member_number" class="form-control" type="text"></div>
</div>
</div>
</div>
{{-- 下部:登録ボタン --}}
<div class="mt-3">
<button type="submit" class="btn btn-sm btn-default">登録</button>
<a href="{{ route('regularcontracts') }}" class="btn btn-sm btn-default">戻る</a>
</div>
</form>
</div>
</div>
</div>
</section>
</div>
@endsection

View File

@ -0,0 +1,77 @@
@extends('layouts.app')
@section('title', '定期契約マスタ - 編集')
@section('content')
<style>
.rc-edit,
.rc-edit .card,
.rc-edit .form-control,
.rc-edit .btn,
.rc-edit .breadcrumb {
font-size: 13px;
}
.rc-toolbar{
display:flex;align-items:center;justify-content:space-between;gap:.75rem;
margin-top:.25rem;margin-bottom:.75rem;
}
.rc-toolbar .left .btn{margin-right:.5rem}
.card .card-header{background:#f5f5f5}
</style>
<div class="rc-edit">
<div class="content-header">
<div class="container-fluid">
<div class="row mb-1">
<div class="col-lg-6"><h1 class="m-0 text-dark">編集</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('regularcontracts') }}">定期契約マスタ</a></li>
<li class="breadcrumb-item active"></li>
</ol>
</div>
</div>
{{-- ここが “目標” のボタン帯 --}}
<div class="rc-toolbar">
<div class="left">
{{-- 登録edit-form submit --}}
<button form="edit-form" type="submit" class="btn btn-success btn-sm">登録</button>
{{-- 領収書発行後で好きなルートに差し替えてOK今はダミー --}}
<button type="button" class="btn btn-success btn-sm" id="btnReceipt">領収書発行</button>
</div>
{{-- 右側:削除 --}}
<form id="del-form" method="post" action="{{ route('regularcontracts_delete') }}" class="m-0">
@csrf
<input type="hidden" name="ids[]" value="{{ $row->contract_id }}">
<button type="submit" class="btn btn-danger btn-sm">削除</button>
</form>
</div>
{{-- /ボタン帯 --}}
</div>
</div>
<section class="content">
<div class="container-fluid">
<div class="card">
{{-- 本体フォーム(登録はこの form submit --}}
<form id="edit-form" method="post" action="{{ route('regularcontracts_edit', ['contract_id'=>$row->contract_id]) }}">
@csrf
@include('admin.regularcontracts._form', array_merge(
['isEdit'=>1,'isInfo'=>0],
(array) $row
))
</form>
</div>
</div>
</section>
</div>
<script>
// 領収書発行はとりあえずダミー動作
document.getElementById('btnReceipt')?.addEventListener('click', function(){
alert('領収書発行の処理をここに実装してください。');
});
</script>
@endsection

View File

@ -0,0 +1,53 @@
@extends('layouts.app')
@section('title', '[東京都|〇〇駐輪場] 定期契約マスタ')
@section('content')
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">[東京都|〇〇駐輪場] 定期契約マスタ</h1>
</div><!-- /.col -->
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="./index2.html">XX様info(ホーム)</a></li>
<li class="breadcrumb-item"><a href="./index3.html">[東京都|〇〇駐輪場]</a></li>
<li class="breadcrumb-item">定期契約マスタ</li>
<li class="breadcrumb-item active">利用者マスタ</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<!-- SELECT2 EXAMPLE -->
<div class="row">
<div class="col-lg-12">
<div class="card">
<form method="post" action="{{ route('regular_contract_info',['id'=>$contract_id])}}" enctype="multipart/form-data">
<!-- TOKEN FORM -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" >
<!-- / .TOKEN FORM -->
@include('admin.regularcontracts._form',['isEdit'=>0,'isInfo'=>1])
</form>
</div>
</div>
</div>
<div class="container-fluid mb20">
<button type="submit" class="btn btn-sm btn-default mr10">{{__('削除')}}</button>
<button type="submit" class="btn btn-sm btn-default mr10">{{__('インポート')}}</button>
<button type="submit" class="btn btn-sm btn-default mr10">{{__('CSV出力')}}</button>
</div>
</div>
</section>
<!-- /.content -->
@endsection

View File

@ -0,0 +1,531 @@
@extends('layouts.app')
@section('title', '定期契約マスタ')
@section('content')
<style>
/* 画面全体のフォント/サイズを統一(やや小さめ) */
.rc-page,
.rc-page .card,
.rc-page .form-control,
.rc-page .btn,
.rc-page table,
.rc-page .breadcrumb {
font-family: "Noto Sans JP", "Hiragino Kaku Gothic ProN", "Meiryo", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 13px;
line-height: 1.45;
}
/* フィルター1行左ラベル右入力、を縦に積む */
.rc-filter .field {
display: flex;
align-items: center;
margin-bottom: .6rem;
}
.rc-filter .label {
flex: 0 0 180px;
margin: 0;
color: #333;
font-weight: 600;
white-space: nowrap;
}
.rc-filter .input {
flex: 1 1 auto;
min-width: 220px;
}
.rc-filter .form-control,
.rc-filter .custom-select {
height: calc(2.0rem + 2px);
padding: .25rem .5rem;
}
.rc-filter .inline-range {
display: flex;
gap: .5rem;
align-items: center;
}
.rc-filter .tilde {
color: #666;
}
/* 一覧テーブル:斑馬(ゼブラ)無し、やや詰め気味 */
.rc-table th,
.rc-table td {
padding: .35rem .5rem;
font-size: 12px;
}
.rc-table thead th {
white-space: nowrap;
}
/* ツールバー:左にボタン群、右にページャ */
.rc-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: .75rem;
flex-wrap: wrap;
}
.rc-toolbar .btn+.btn {
margin-left: .4rem;
}
/* 表頭=薄いグレー、本文=白 */
.rc-page .rc-table thead th {
background: #f2f2f2;
color: #333;
border-bottom-color: #ddd;
}
.rc-page .rc-table tbody td:not(.op-cell) {
background: #fff;
}
/* 操作列(チェック+編集) */
.rc-page .rc-table tbody td.op-cell {
background: #faebd7;
}
</style>
<div class="rc-page">
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">定期契約マスタ</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item active">定期契約マスタ</li>
</ol>
</div>
</div>
<p class="text-muted mb-0">※この画面のデータは通常変更する必要はありません。</p>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 絞り込みフィルター2カラム --}}
<div class="card rc-filter">
<div class="card-header">
<h3 class="card-title">絞り込みフィルター</h3>
</div>
<div class="card-body">
<form action="{{ route('regularcontracts') }}" method="post" id="list-form">
@csrf
<input type="hidden" name="sort" id="sort" value="{{ $sort }}">
<input type="hidden" name="sort_type" id="sort_type" value="{{ $sort_type }}">
<div class="row">
{{-- 左カラム --}}
<div class="col-lg-6">
<div class="field">
<label class="label">利用者ID</label>
<div class="input"><input type="text" class="form-control" name="user_id" value="{{ $user_id ?? '' }}"
placeholder="123456"></div>
</div>
<div class="field">
<label class="label">利用者分類</label>
<div class="input"><input type="text" class="form-control" name="usertype_name"
value="{{ $usertype_name ?? '' }}" placeholder="キーワード…"></div>
</div>
<div class="field">
<label class="label">タグシリアル</label>
<div class="input"><input type="text" class="form-control" name="user_tag_serial"
value="{{ $user_tag_serial ?? '' }}" placeholder="キーワード…"></div>
</div>
<div class="field">
<label class="label">フリガナ</label>
<div class="input"><input type="text" class="form-control" name="user_phonetic"
value="{{ $user_phonetic ?? '' }}" placeholder="キーワード…"></div>
</div>
<div class="field">
<label class="label">電話番号</label>
<div class="input"><input type="text" class="form-control" name="phone" value="{{ $phone ?? '' }}"
placeholder="携帯/自宅いずれも可"></div>
</div>
<div class="field">
<label class="label">メールアドレス</label>
<div class="input"><input type="text" class="form-control" name="email" value="{{ $email ?? '' }}">
</div>
</div>
<div class="field">
<label class="label">ワークレコード</label>
<div class="input">
<select class="form-control" name="work_record">
<option value="">ワークレコード非表示</option>
</select>
</div>
</div>
<div class="field">
<label class="label">定期契約ID</label>
<div class="input"><input type="text" class="form-control" name="contract_qr_id"
value="{{ $contract_qr_id ?? '' }}"></div>
</div>
<div class="field">
<label class="label">検索</label>
<div class="input"><input type="text" class="form-control" name="zone_keyword"
value="{{ $zone_keyword ?? '' }}" placeholder="ゾーンID, 車室番号, 旧会員番号"></div>
</div>
<div class="field">
<label class="label">関連住所入力あり</label>
<div class="input">
<div class="form-check" style="padding-left:0;">
<input type="checkbox" class="form-check-input" id="has_address" name="has_address" value="1" {{ !empty($has_address) ? 'checked' : '' }}>
</div>
</div>
</div>
</div>
{{-- 右カラム --}}
<div class="col-lg-6">
<div class="field">
<label class="label">駐輪場</label>
<div class="input"><input type="text" class="form-control" name="park_name"
value="{{ $park_name ?? '' }}" placeholder="キーワード…"></div>
</div>
<div class="field">
<label class="label">予約日時</label>
<div class="input inline-range">
<input type="datetime-local" class="form-control" name="reserve_date_from"
value="{{ $reserve_date_from ?? '' }}">
<span class="tilde"></span>
<input type="datetime-local" class="form-control" name="reserve_date_to"
value="{{ $reserve_date_to ?? '' }}">
</div>
</div>
<div class="field">
<label class="label">契約日時</label>
<div class="input inline-range">
<input type="datetime-local" class="form-control" name="contract_created_from"
value="{{ $contract_created_from ?? '' }}">
<span class="tilde"></span>
<input type="datetime-local" class="form-control" name="contract_created_to"
value="{{ $contract_created_to ?? '' }}">
</div>
</div>
<div class="field">
<label class="label">解約日時</label>
<div class="input inline-range">
<input type="datetime-local" class="form-control" name="contract_canceled_from"
value="{{ $contract_canceled_from ?? '' }}">
<span class="tilde"></span>
<input type="datetime-local" class="form-control" name="contract_canceled_to"
value="{{ $contract_canceled_to ?? '' }}">
</div>
</div>
<div class="field">
<label class="label">授受日時</label>
<div class="input inline-range">
<input type="datetime-local" class="form-control" name="receipt_delivery_from"
value="{{ $receipt_delivery_from ?? '' }}">
<span class="tilde"></span>
<input type="datetime-local" class="form-control" name="receipt_delivery_to"
value="{{ $receipt_delivery_to ?? '' }}">
</div>
</div>
<div class="field">
<label class="label">定期有効月数</label>
<div class="input"><input type="number" min="0" class="form-control" name="contract_valid_months"
value="{{ $contract_valid_months ?? '' }}"></div>
</div>
<div class="field">
<label class="label">定期契約継続</label>
<div class="input">
<select class="form-control" name="update_flag">
<option value="">全て</option>
<option value="1" {{ (isset($update_flag) && (string) $update_flag === '1') ? 'selected' : '' }}>ON
</option>
<option value="0" {{ (isset($update_flag) && (string) $update_flag === '0') ? 'selected' : '' }}>未更新
</option>
</select>
</div>
</div>
<div class="field">
<label class="label">名寄フリガナ</label>
<div class="input"><input type="text" class="form-control" name="merge_phonetic"
value="{{ $merge_phonetic ?? '' }}" placeholder="キーワード…"></div>
</div>
<div class="field">
<label class="label">ゾーン名検索</label>
<div class="input"><input type="text" class="form-control" name="zone_name"
value="{{ $zone_name ?? '' }}" placeholder="キーワード…"></div>
</div>
<div class="field">
<label class="label">タグ・QR</label>
<div class="input">
<select class="form-control" name="tag_qr_flag">
<option value="">全て</option>
<option value="0" {{ (isset($tag_qr_flag) && (string) $tag_qr_flag === '0') ? 'selected' : '' }}>タグ
</option>
<option value="1" {{ (isset($tag_qr_flag) && (string) $tag_qr_flag === '1') ? 'selected' : '' }}>QR
</option>
</select>
</div>
</div>
</div>
</div>
{{-- フィルターボタン(見た目統一) --}}
<div class="mt-2">
<button type="submit" class="btn btn-default">絞り込み</button>
<a href="{{ route('regularcontracts') }}" class="btn btn-default">解除</a>
</div>
</form>
</div>
</div>
{{-- ツールバー:左=ボタン群、右=ページャ --}}
<div class="rc-toolbar mb-2">
<div class="left">
<a href="{{ route('regularcontracts_add') }}" class="btn btn-sm btn-default">新規</a>
<button type="button" class="btn btn-sm btn-default" data-toggle="modal"
data-target="#importModal">インポート</button>
{{-- 3種のエクスポートは共通の確認モーダルを使い、data-url に出力先URLを渡す --}}
<button type="button" class="btn btn-sm btn-default" data-toggle="modal" data-target="#exportModal"
data-url="{{ route('regularcontracts_export') }}">CSV出力</button>
<button type="button" class="btn btn-sm btn-default" data-toggle="modal" data-target="#exportModal"
data-url="{{ route('regularcontracts_export', [], false) }}?type=smbc">SMBC出力</button>
<button type="button" class="btn btn-sm btn-default" data-toggle="modal" data-target="#exportModal"
data-url="{{ route('regularcontracts_export', [], false) }}?type=city">役所提出用CSV出力</button>
</div>
<div class="right">
{{ $list->appends(['sort' => $sort, 'sort_type' => $sort_type])->links('pagination') }}
</div>
</div>
<iframe id="dlFrame" name="dlFrame" style="width:0;height:0;border:0;visibility:hidden;"></iframe>
{{-- 一覧テーブル --}}
<form action="{{ route('regularcontracts_delete') }}" method="post" id="form_delete">
@csrf
<div class="table-responsive">
<table class="table table-bordered table-hover rc-table mb-0 text-nowrap">
<thead>
<tr>
@php $next = ($sort === 'contract_id' && $sort_type === 'asc') ? 'desc' : 'asc'; @endphp
<th class="text-right" style="white-space:nowrap;">
<a title="contract_idで並び替え"
href="{{ route('regularcontracts', array_merge(request()->except('page'), ['sort' => 'contract_id', 'sort_type' => $next])) }}"></a>
</th>
{{-- 操作列(チェック+編集。背景色を付与) --}}
<th style="width:120px"></th>
{{-- 表頭(要件に合わせて網羅) --}}
<th>定期契約ID</th>
<th>旧定期契約番号</th>
<th>ゾーンID</th>
<th>車室番号</th>
<th>利用者ID</th>
<th>利用者分類ID</th>
<th>タグ・QR</th>
<th>駐輪場ID</th>
<th>有効期間S</th>
<th>有効期間E</th>
<th>駐輪場所ID</th>
<th>防犯登録番号</th>
<th>契約日時</th>
<th>更新可能日</th>
<th>解約日時</th>
<th>減免措置</th>
<th>定期有効月数</th>
<th>シール印刷可能日</th>
<th>請求金額</th>
<th>車室割り当てフラグ</th>
<th>授受日時</th>
<th>授受金額</th>
<th>授受フラグ</th>
<th>決済トランザクションID</th>
<th>シール発行数</th>
<th>シール発行許可</th>
<th>解約フラグ</th>
<th>収納企業コード</th>
<th>共有先収納企業コード</th>
<th>受付番号</th>
<th>(更新元)契約更新済フラグ</th>
<th>車種区分ID</th>
<th>チェック用_フリガナ</th>
<th>チェック用_居住所郵便番号</th>
<th>チェック用_携帯電話番号</th>
<th>チェック用_自宅電話番号</th>
<th>チェック用_旧会員番号</th>
</tr>
</thead>
<tbody>
@foreach($list as $item)
<tr>
{{-- 先頭の並び替え列(行の contract_id を表示) --}}
<td class="text-right">{{ $item->contract_id }}</td>
{{-- 操作列:チェック + 編集(背景色つき) --}}
<td class="op-cell">
<div class="d-flex align-items-center">
<input type="checkbox" class="mr-2" name="ids[]" value="{{ $item->contract_id }}">
<a href="{{ route('regularcontracts_edit', ['contract_id' => $item->contract_id]) }}"
class="btn btn-sm btn-default">編集</a>
</div>
</td>
{{-- データ列 --}}
<td class="text-right">{{ $item->contract_qr_id }}</td>
<td>{{ $item->old_contract_number ?? '' }}</td>
<td>{{ $item->zone_id ?? '' }}</td>
<td>{{ $item->room_number ?? '' }}</td>
<td class="text-right">{{ $item->user_id }}</td>
<td class="text-right">{{ $item->user_categoryid }}</td>
<td>{{ $item->tag_qr_flag ? 'QR' : 'タグ' }}</td>
<td class="text-right">{{ $item->park_id }}</td>
<td>{{ $item->valid_from ?? '' }}</td>
<td>{{ $item->valid_to ?? '' }}</td>
<td class="text-right">{{ $item->price_arkplaceid ?? $item->price_parkplaceid ?? '' }}</td>
<td>{{ $item->crime_prevention_registration_number ?? '' }}</td>
<td>{{ $item->contract_created_at ?? '' }}</td>
<td>{{ $item->renewable_date ?? '' }}</td>
<td>{{ $item->contract_cancelday ?? '' }}</td>
<td>{{ $item->reduction ?? '' }}</td>
<td class="text-right">{{ $item->contract_valid_months ?? '' }}</td>
<td>{{ $item->label_printable_date ?? '' }}</td>
<td class="text-right">{{ $item->billing_amount ?? '' }}</td>
<td>{{ ($item->assign_flag ?? null) === null ? '' : (($item->assign_flag) ? '割当済' : '未割当') }}</td>
<td>{{ $item->receipt_delivery_date ?? '' }}</td>
<td class="text-right">{{ $item->receipt_delivery_amount ?? '' }}</td>
<td>
{{ ($item->receipt_delivery_flag ?? null) === null ? '' : (($item->receipt_delivery_flag) ? '済' : '未') }}
</td>
<td>{{ $item->payment_transaction_id ?? '' }}</td>
<td class="text-right">{{ $item->label_issue_count ?? '' }}</td>
<td>{{ ($item->contract_permission ?? 0) ? '許可' : '未許可' }}</td>
<td>{{ ($item->contract_cancel_flag ?? 0) ? 'キャンセル' : '' }}</td>
<td>{{ $item->company_code ?? '' }}</td>
<td>{{ $item->shared_company_code ?? '' }}</td>
<td>{{ $item->accept_number ?? '' }}</td>
<td>{{ ($item->update_flag ?? 0) ? '更新済' : '未更新' }}</td>
<td>{{ $item->vehicle_type_id ?? '' }}</td>
<td>{{ $item->user_phonetic ?? '' }}</td>
<td>{{ $item->user_regident_zip ?? '' }}</td>
<td>{{ $item->user_mobile ?? '' }}</td>
<td>{{ $item->user_homephone ?? '' }}</td>
<td>{{ $item->old_member_number ?? '' }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</form>
{{-- 下側のページャ(右寄せ) --}}
<div class="d-flex justify-content-end mt-2">
{{ $list->appends(['sort' => $sort, 'sort_type' => $sort_type])->links('pagination') }}
</div>
</div>
</section>
</div>
{{-- インポート用モーダル(ファイル選択) --}}
<div class="modal fade" id="importModal" tabindex="-1" role="dialog" aria-labelledby="importModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header py-2">
<h5 class="modal-title" id="importModalLabel">確認</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<form method="post" action="{{ route('regularcontracts_import') }}" enctype="multipart/form-data">
@csrf
<div class="modal-body">
<p class="mb-2 text-sm">
データをインポートします。既存データを上書きする場合はテンプレートに従い識別列を設定してください。<br>
新規追加のみの場合は識別列を空欄のままインポートしてください。
</p>
<div class="custom-file">
<input type="file" name="file" id="importFile" class="custom-file-input" accept=".csv,.xlsx,.xls,.tsv,.txt"
required>
<label class="custom-file-label" for="importFile">ファイルの選択</label>
</div>
</div>
<div class="modal-footer py-2">
<button type="submit" class="btn btn-primary btn-sm">はい</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">いいえ</button>
</div>
</form>
</div>
</div>
</div>
{{-- エクスポート用モーダル(確認のみ。リンク先でダウンロード) --}}
<div class="modal fade" id="exportModal" tabindex="-1" role="dialog" aria-labelledby="exportModalLabel"
aria-hidden="true">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header py-2">
<h5 class="modal-title" id="exportModalLabel">確認</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body text-sm">CSVファイルを出力します。よろしいですか</div>
<div class="modal-footer py-2">
<a id="exportGo" href="#" class="btn btn-primary btn-sm">はい</a>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">いいえ</button>
</div>
</div>
</div>
</div>
{{-- 画面内スクリプトインポートのファイル名表示、エクスポートのURL差し替え --}}
<script>
// インポート:選択したファイル名をラベルに反映
document.addEventListener('change', function (e) {
if (e.target && e.target.id === 'importFile') {
var label = e.target.nextElementSibling;
if (label) label.textContent = e.target.files.length ? e.target.files[0].name : 'ファイルの選択';
}
});
// エクスポート:モーダル表示時に押下ボタンの data-url を「はい」へセット
(function () {
var $ = window.jQuery;
var $exportGo = $('#exportGo');
var $exportModal = $('#exportModal');
if ($ && $exportModal.length) {
// モーダルが開く時に URL を保持href と data-href の両方に入れておく)
$exportModal.on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);
var url = button && button.data('url');
$exportGo.attr('href', url || '#');
$exportGo.attr('data-href', url || '#');
});
// 「はい」→ 既定遷移を止め、隠し iframe でダウンロード開始 → モーダル閉じる
$exportGo.on('click', function (e) {
e.preventDefault();
var url = $(this).attr('data-href') || $(this).attr('href') || '#';
if (url && url !== '#') {
var iframe = document.getElementById('dlFrame');
if (iframe) {
iframe.src = url; // ここでダウンロード開始(ページ遷移なし)
} else {
// 念のためのフォールバック
window.location.href = url;
}
}
$exportModal.modal('hide');
});
}
})();
</script>
@endsection

View File

@ -0,0 +1,211 @@
@extends('layouts.app')
@section('title', '予約者一覧')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0 text-dark">予約者一覧</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item active">予約者一覧</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 絞り込みフィルター(順序を画像に完全一致) --}}
<form method="GET" action="{{ route('reservation') }}" class="mb-3" id="filter-form">
<div class="card p-3">
<h6 class="mb-3">絞り込みフィルター</h6>
<div class="row">
{{-- 左カラム:駐輪場 利用者ID 利用者分類 タグシリアル タグシリアル64進 --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">駐輪場</label>
<div class="col-sm-9">
@isset($parks)
<select name="park_id" class="form-control">
<option value="">全て</option>
@foreach($parks as $p)
<option value="{{ $p->park_id }}" {{ (string)request('park_id')===(string)$p->park_id ? 'selected' : '' }}>
{{ $p->park_name }}
</option>
@endforeach
</select>
@else
<input type="text" name="park_name" value="{{ request('park_name') }}" class="form-control" placeholder="全て">
@endisset
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者ID</label>
<div class="col-sm-9">
<input type="text" name="user_id" value="{{ request('user_id') }}" class="form-control" placeholder="123456">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者分類</label>
<div class="col-sm-9">
<input type="text" name="user_categoryid" value="{{ request('user_categoryid') }}" class="form-control" placeholder="全て">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグシリアル</label>
<div class="col-sm-9">
<input type="text" name="user_tag_serial" value="{{ request('user_tag_serial') }}" class="form-control" placeholder="キーワード…">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグシリアル64進</label>
<div class="col-sm-9">
<input type="text" name="user_tag_serial_64" value="{{ request('user_tag_serial_64') }}" class="form-control" placeholder="キーワード…">
</div>
</div>
</div>
{{-- 右カラム:フリガナ 電話番号 メールアドレス 勤務先 学校 --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">フリガナ</label>
<div class="col-sm-9">
<input type="text" name="user_phonetic" value="{{ request('user_phonetic') }}" class="form-control" placeholder="123456">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">電話番号</label>
<div class="col-sm-9">
<input type="text" name="user_mobile" value="{{ request('user_mobile') }}" class="form-control" placeholder="123456">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">メールアドレス</label>
<div class="col-sm-9">
<input type="text" name="user_primemail" value="{{ request('user_primemail') }}" class="form-control" placeholder="キーワード…">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">勤務先</label>
<div class="col-sm-9">
<input type="text" name="user_workplace" value="{{ request('user_workplace') }}" class="form-control" placeholder="キーワード…">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">学校</label>
<div class="col-sm-9">
<input type="text" name="user_school" value="{{ request('user_school') }}" class="form-control" placeholder="キーワード…">
</div>
</div>
</div>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-default">絞り込み</button>
<a href="{{ route('reservation') }}" class="btn btn-default">解除</a>
</div>
</div>
</form>
{{-- 一覧テーブル(そのまま) --}}
<div class="table-responsive">
<table class="table table-bordered table-hover table-sm rv-table text-nowrap">
<thead>
<tr>
<th>利用者ID</th>
<th>氏名</th>
<th>フリガナ</th>
<th>居住所:郵便番号</th>
<th>居住所:都道府県</th>
<th>居住所:市区群</th>
<th>居住所:住所</th>
<th>関連住所:郵便番号</th>
<th>関連住所:都道府県</th>
<th>関連住所:市区群</th>
<th>関連住所:住所</th>
<th>生年月日</th>
<th>性別</th>
<th>携帯電話番号</th>
<th>自宅電話番号</th>
<th>学校</th>
<th>卒業予定</th>
<th>備考</th>
<th>定期予約ID</th>
<th>利用者分類1</th>
<th>利用者分類2</th>
<th>利用者分類3</th>
<th>駐輪場ID</th>
<th>駐輪場名</th> <!-- 追加 -->
<th>駐輪場所ID</th>
<th>車種区分ID</th>
<th>予約日時</th>
<th>減免措置</th>
<th>800M以内フラグ</th>
</tr>
</thead>
<tbody>
@forelse ($rows as $row)
<tr>
<td>{{ $row->user_id }}</td>
<td>{{ $row->user_name }}</td>
<td>{{ $row->user_phonetic }}</td>
<td>{{ $row->user_regident_zip }}</td>
<td>{{ $row->user_regident_pre }}</td>
<td>{{ $row->user_regident_city }}</td>
<td>{{ $row->user_regident_add }}</td>
<td>{{ $row->user_relate_zip }}</td>
<td>{{ $row->user_relate_pre }}</td>
<td>{{ $row->user_relate_city }}</td>
<td>{{ $row->user_relate_add }}</td>
<td>{{ $row->user_birthdate }}</td>
<td>{{ $row->user_gender }}</td>
<td>{{ $row->user_mobile }}</td>
<td>{{ $row->user_homephone }}</td>
<td>{{ $row->user_school }}</td>
<td>{{ $row->user_graduate }}</td>
<td>{{ $row->user_remarks }}</td>
<td>{{ data_get($row,'reserve_id', data_get($row,'contract_id','')) }}</td>
<td>{{ $row->park_id }}</td>
<td>{{ $row->park_name }}</td>
<td>{{ $row->price_parkplaceid }}</td>
<td>{{ $row->psection_id }}</td>
<td>{{ $row->reserve_date }}</td>
<td>{{ data_get($row,'reduction', data_get($row,'reserve_reduction','')) }}</td>
<td>
@php $f800 = data_get($row,'within_800m_flag', data_get($row,'flag_800m', null)); @endphp
{{ (string)$f800 === '1' ? '800M以内' : '' }}
</td>
</tr>
@empty
<tr><td colspan="29" class="text-center">データがありません。</td></tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-3">
{{ $rows->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
</div>
</section>
<style>
.rv-table thead th{ background:#eeeeee; white-space:nowrap; vertical-align:middle; }
.rv-table tbody tr{ background:#fff; }
</style>
@endsection

View File

@ -0,0 +1,277 @@
@extends('layouts.app')
@section('title', '定期予約登録')
@section('content')
<style>
/* 画面全体のフォント/サイズを統一(やや小さめ) */
.rv-add,
.rv-add .card,
.rv-add .form-control,
.rv-add .btn,
.rv-add .breadcrumb {
font-family: "Noto Sans JP","Hiragino Kaku Gothic ProN","Meiryo",system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
font-size: 13px;
line-height: 1.45;
}
/* 1行左ラベル右入力 */
.rv-add .field{display:flex;align-items:center;margin-bottom:.7rem;}
.rv-add .label{flex:0 0 170px;margin:0;color:#333;font-weight:600;white-space:nowrap;}
.rv-add .input{flex:1 1 auto;}
.rv-add .form-control{height:calc(2.0rem + 2px);padding:.25rem .5rem;}
.rv-add .help{color:#888;font-size:12px;}
</style>
<div class="rv-add">
{{-- パンくず&見出し --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">新規</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('reserves') }}">定期予約マスタ</a></li>
<li class="breadcrumb-item active">新規</li>
</ol>
</div>
</div>
@if($errors->any())
<div class="alert alert-danger py-2 px-3 my-2">
<ul class="mb-0">
@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach
</ul>
</div>
@endif
</div>
</div>
<section class="content">
<div class="container-fluid">
<div class="card">
<div class="card-header py-2">
<button form="rvAddForm" type="submit" class="btn btn-success btn-sm">登録</button>
</div>
<form id="rvAddForm" method="post" action="{{ route('reserves_add') }}">
@csrf
<div class="card-body">
{{-- 画面上部ID系 --}}
<div class="field">
<label class="label">定期予約ID</label>
<div class="input">
<input type="text" class="form-control" value="(自動採番)" disabled>
</div>
</div>
<div class="field">
<label class="label">定期契約ID</label>
<div class="input">
<input type="number" class="form-control" name="contract_id" value="{{ old('contract_id') }}">
</div>
</div>
<div class="field">
<label class="label">利用者分類ID</label>
<div class="input">
{{-- 任意:必要に応じて選択肢を与える(今は簡易にテキスト or 「全て」) --}}
<select name="user_categoryid" class="form-control">
<option value="">全て</option>
</select>
</div>
</div>
<div class="field">
<label class="label">利用者登録日時</label>
<div class="input">
<input type="datetime-local" class="form-control" name="user_created_at" value="{{ old('user_created_at') }}">
</div>
</div>
{{-- 基本情報 --}}
<div class="field">
<label class="label">利用者ID <span class="text-danger">*</span></label>
<div class="input">
<input type="number" class="form-control" name="user_id" value="{{ old('user_id') }}" required>
</div>
</div>
<div class="field">
<label class="label">駐輪場ID <span class="text-danger">*</span></label>
<div class="input">
<input type="number" class="form-control" name="park_id" value="{{ old('park_id') }}" required>
</div>
</div>
<div class="field">
<label class="label">駐輪場所ID</label>
<div class="input">
<input type="number" class="form-control" name="price_parkplaceid" value="{{ old('price_parkplaceid') }}">
</div>
</div>
<div class="field">
<label class="label">車種区分ID</label>
<div class="input">
<input type="number" class="form-control" name="psection_id" value="{{ old('psection_id') }}">
</div>
</div>
<div class="field">
<label class="label">駐輪分類ID</label>
<div class="input">
<input type="number" class="form-control" name="ptype_id" value="{{ old('ptype_id') }}">
</div>
</div>
<div class="field">
<label class="label">予約日時</label>
<div class="input">
<input type="datetime-local" class="form-control" name="reserve_date" value="{{ old('reserve_date') }}">
</div>
</div>
{{-- ラジオ系 --}}
<div class="field">
<label class="label">減免措置</label>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="reduction_flag" id="reduction1" value="1" {{ old('reduction_flag','0')==='1'?'checked':'' }}>
<label class="form-check-label" for="reduction1">あり</label>
</div>
<div class="form-check form-check-inline ml-3">
<input class="form-check-input" type="radio" name="reduction_flag" id="reduction0" value="0" {{ old('reduction_flag','0')==='0'?'checked':'' }}>
<label class="form-check-label" for="reduction0">なし</label>
</div>
</div>
</div>
{{-- リマインド --}}
<div class="field">
<label class="label">自動リマインド日</label>
<div class="input">
<input type="date" class="form-control" name="auto_remind_day" value="{{ old('auto_remind_day') }}">
</div>
</div>
<div class="field">
<label class="label">手動リマインド日</label>
<div class="input">
<input type="date" class="form-control" name="manual_remind_day" value="{{ old('manual_remind_day') }}">
</div>
</div>
<div class="field">
<label class="label">800M以内フラグ</label>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="within_800m_flag" id="m800_1" value="1" {{ old('within_800m_flag','0')==='1'?'checked':'' }}>
<label class="form-check-label" for="m800_1">M以内</label>
</div>
<div class="form-check form-check-inline ml-3">
<input class="form-check-input" type="radio" name="within_800m_flag" id="m800_0" value="0" {{ old('within_800m_flag','0')==='0'?'checked':'' }}>
<label class="form-check-label" for="m800_0">M内ではない</label>
</div>
</div>
</div>
{{-- 期間・状態 --}}
<div class="field">
<label class="label">解約日</label>
<div class="input">
<input type="date" class="form-control" name="reserve_cancelday" value="{{ old('reserve_cancelday') }}">
</div>
</div>
<div class="field">
<label class="label">有効フラグ</label>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="valid_flag" id="valid1" value="1" {{ old('valid_flag','1')==='1'?'checked':'' }}>
<label class="form-check-label" for="valid1">有効</label>
</div>
<div class="form-check form-check-inline ml-3">
<input class="form-check-input" type="radio" name="valid_flag" id="valid0" value="0" {{ old('valid_flag')==='0'?'checked':'' }}>
<label class="form-check-label" for="valid0">無効</label>
</div>
</div>
</div>
{{-- 通知 --}}
<div class="field">
<label class="label">手動通知</label>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="manual_notice" id="mn1" value="1" {{ old('manual_notice','0')==='1'?'checked':'' }}>
<label class="form-check-label" for="mn1">手動通知</label>
</div>
<div class="form-check form-check-inline ml-3">
<input class="form-check-input" type="radio" name="manual_notice" id="mn2" value="2" {{ old('manual_notice')==='2'?'checked':'' }}>
<label class="form-check-label" for="mn2">メール通知</label>
</div>
</div>
</div>
<div class="field">
<label class="label">手動通知方法</label>
<div class="input">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="manual_notice_method" id="mm_tel" value="tel" {{ old('manual_notice_method','tel')==='tel'?'checked':'' }}>
<label class="form-check-label" for="mm_tel">電話</label>
</div>
<div class="form-check form-check-inline ml-3">
<input class="form-check-input" type="radio" name="manual_notice_method" id="mm_mail" value="post" {{ old('manual_notice_method')==='post'?'checked':'' }}>
<label class="form-check-label" for="mm_mail">郵送</label>
</div>
</div>
</div>
<div class="field">
<label class="label">空き待ちメール送信日時</label>
<div class="input">
<input type="datetime-local" class="form-control" name="waiting_mail_sent_at" value="{{ old('waiting_mail_sent_at') }}">
</div>
</div>
<div class="field">
<label class="label">空き待ち順</label>
<div class="input">
<input type="number" class="form-control" name="waiting_order" value="{{ old('waiting_order') }}">
<div class="help">小さいほど優先度が高い想定</div>
</div>
</div>
{{-- 任意:開始/終了(必要なら表示) --}}
<div class="field">
<label class="label">開始日</label>
<div class="input">
<input type="date" class="form-control" name="reserve_start" value="{{ old('reserve_start') }}">
</div>
</div>
<div class="field">
<label class="label">終了日</label>
<div class="input">
<input type="date" class="form-control" name="reserve_end" value="{{ old('reserve_end') }}">
</div>
</div>
<div class="field">
<label class="label">オペレータID</label>
<div class="input">
<input type="number" class="form-control" name="ope_id" value="{{ old('ope_id') }}">
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success">登録</button>
<a href="{{ route('reserves') }}" class="btn btn-default ml-2">戻る</a>
</div>
</form>
</div>
</div>
</section>
</div>
@endsection

View File

@ -0,0 +1,123 @@
{{-- resources/views/admin/reserves/delete.blade.php --}}
@extends('layouts.app')
@section('title', '定期予約 削除確認')
@section('content')
@php
// === 削除対象IDを堅牢に収集$rows / $ids / request('ids') のいずれでも可)===
$collectedIds = [];
if (!empty($rows)) {
foreach ($rows as $r) { $collectedIds[] = (int)$r->reserve_id; }
} elseif (!empty($ids)) {
$collectedIds = array_map('intval', (array)$ids);
} else {
// クエリやPOSTで "ids" が来ている場合ids[]= / ids=1,2 どちらも吸収)
$raw = request()->input('ids', []);
if (is_string($raw)) $raw = explode(',', $raw);
$collectedIds = array_map('intval', (array)$raw);
}
$collectedIds = array_values(array_unique(array_filter($collectedIds, fn($v)=>$v>0)));
@endphp
<style>
/* 画面全体を小さめの文字で統一 */
.rs-del-page, .rs-del-page .card, .rs-del-page .btn, .rs-del-page table { font-size: 13px; }
</style>
<div class="rs-del-page">
{{-- ヘッダー / パンくず --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6"><h1 class="m-0 text-dark">削除確認</h1></div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('reserves') }}">定期予約マスタ</a></li>
<li class="breadcrumb-item active">削除確認</li>
</ol>
</div>
</div>
@if(count($collectedIds))
<div class="alert alert-warning mb-0">
選択した定期予約を<strong>削除</strong>します。この操作は取り消せません。よろしいですか?
</div>
@else
<div class="alert alert-danger mb-0">
削除対象が選択されていません。一覧に戻って、チェックボックスで対象を選択してください。
</div>
@endif
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 対象一覧(可能なら情報を表示。$rows が無いときはIDのバッジだけ --}}
<div class="card">
<div class="card-header py-2">
<h3 class="card-title">削除対象</h3>
</div>
<div class="card-body p-2">
@if(!empty($rows) && count($rows))
<div class="table-responsive">
<table class="table table-bordered table-hover mb-2">
<thead>
<tr>
<th style="white-space:nowrap;">予約ID</th>
<th>定期契約ID</th>
<th>利用者名</th>
<th>駐輪場</th>
<th>予約日時</th>
</tr>
</thead>
<tbody>
@foreach($rows as $r)
<tr>
<td class="text-right">{{ $r->reserve_id }}</td>
<td class="text-right">{{ $r->contract_id ?? '' }}</td>
<td>{{ $r->user_name ?? '' }}</td>
<td>{{ $r->park_name ?? '' }}</td>
{{-- 実テーブル列名に合わせて reserve_date を使用 --}}
<td>{{ $r->reserve_date ?? '' }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@elseif(count($collectedIds))
<p class="mb-2">
削除対象ID
@foreach($collectedIds as $id)
<span class="badge badge-secondary mr-1">{{ $id }}</span>
@endforeach
</p>
@else
<p class="text-muted mb-0">削除対象が取得できませんでした。</p>
@endif
</div>
</div>
{{-- 確認フォーム --}}
<form action="{{ route('reserves_delete') }}" method="post" class="mt-2">
@csrf
{{-- コントローラ側で「確認済み」を判定できるようにフラグを送る --}}
<input type="hidden" name="confirmed" value="1">
{{-- hidden に対象 ID を埋め込む --}}
@foreach($collectedIds as $id)
<input type="hidden" name="ids[]" value="{{ $id }}">
@endforeach
<a href="{{ route('reserves') }}" class="btn btn-default">キャンセル</a>
<button type="submit" class="btn btn-danger"
{{ count($collectedIds) ? '' : 'disabled' }}>
削除する
</button>
</form>
</div>
</section>
</div>
@endsection

View File

@ -0,0 +1,340 @@
{{-- resources/views/admin/reserves/edit.blade.php --}}
@extends('layouts.app')
@section('title', '定期予約マスタ - 編集')
@section('content')
<style>
.rv-edit, .rv-edit .card, .rv-edit .form-control, .rv-edit .btn, .rv-edit .breadcrumb{
font-family:"Noto Sans JP","Hiragino Kaku Gothic ProN","Meiryo",system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
font-size:13px; line-height:1.45;
}
.rv-form .field{display:flex;align-items:center;margin-bottom:.7rem;}
.rv-form .label{flex:0 0 180px;margin:0;color:#333;font-weight:600;white-space:nowrap;}
.rv-form .input{flex:1 1 auto;min-width:260px;}
.rv-form .form-control{height:calc(2.0rem + 2px);padding:.25rem .5rem;}
/* 目标图没有灰色表头,这里直接隐藏 */
.card .card-header{display:none;}
.rv-toolbar .btn+.btn{margin-left:.4rem;}
.help-text{color:#666;font-size:12px;}
</style>
@php
// 只读显示用:从现有 options 推断名称(不改控制器也能显示)
$userName = '';
if (!empty($row->user_id ?? null) && !empty($userOptions[$row->user_id] ?? null)) {
// $userOptions 形如 "12345 山田太郎" → 去掉开头ID只留名字
$userName = trim(preg_replace('/^\s*\d+\s*/', '', $userOptions[$row->user_id]));
}
$parkName = '';
if (!empty($row->park_id ?? null) && !empty($parkOptions[$row->park_id] ?? null)) {
$parkName = trim(preg_replace('/^\s*\d+\s*/', '', $parkOptions[$row->park_id]));
}
@endphp
<div class="rv-edit">
{{-- ヘッダ --}}
<div class="content-header">
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-2">
<h1 class="m-0 text-dark">編集</h1>
</div>
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('reserves') }}">定期予約マスタ</a></li>
<li class="breadcrumb-item active">編集</li>
</ol>
@if(session('success'))
<div class="alert alert-success py-2 px-3 my-2">{{ session('success') }}</div>
@endif
@if($errors->any())
<div class="alert alert-danger py-2 px-3 my-2">
<ul class="mb-0">@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul>
</div>
@endif
</div>
</div>
{{-- 本体 --}}
<section class="content">
<div class="container-fluid">
<div class="card rv-form">
{{-- GET と同一ルートで POST 更新 --}}
<form id="edit-form" method="post" action="{{ route('reserves_edit', ['reserve_id'=>$row->reserve_id]) }}">
@csrf
<div class="card-body">
<div class="row">
{{-- 左カラム(目标图顺序) --}}
<div class="col-lg-6">
{{-- 定期予約ID読み取り --}}
<div class="field">
<label class="label">定期予約ID</label>
<div class="input"><input type="text" class="form-control" value="{{ $row->reserve_id }}" readonly></div>
</div>
{{-- 定期契約ID --}}
<div class="field">
<label class="label">定期契約ID</label>
<div class="input">
<input type="text" name="contract_id" class="form-control"
value="{{ old('contract_id', $row->contract_id ?? '') }}"
placeholder="定期契約ID">
</div>
</div>
{{-- 利用者分類ID先頭「全て」 --}}
<div class="field">
<label class="label">利用者分類ID</label>
<div class="input">
<select name="user_categoryid" class="form-control">
<option value="">全て</option>
@if(!empty($userTypeOptions))
@foreach($userTypeOptions as $k=>$v)
<option value="{{ $k }}" {{ (string)old('user_categoryid', $row->user_categoryid ?? '')===(string)$k?'selected':'' }}>
{{ $v }}
</option>
@endforeach
@endif
</select>
</div>
</div>
{{-- 予約日時 --}}
<div class="field">
<label class="label">予約日時</label>
<div class="input">
<input type="text" name="reserve_date" class="form-control"
placeholder="yyyy/mm/dd hh:mm:ss"
value="{{ old('reserve_date', $row->reserve_date ?? '') }}">
</div>
</div>
{{-- 利用者名(読み取り)※目標画面に合わせて表示のみ --}}
<div class="field">
<label class="label">利用者名</label>
<div class="input"><input type="text" class="form-control" value="{{ $userName }}" readonly></div>
</div>
{{-- 利用者ID --}}
<div class="field">
<label class="label">利用者ID</label>
<div class="input">
<select name="user_id" class="form-control">
<option value="">選択してください</option>
@if(!empty($userOptions))
@foreach($userOptions as $k=>$v)
<option value="{{ $k }}" {{ (string)old('user_id', $row->user_id ?? '')===(string)$k?'selected':'' }}>
{{ $v }}
</option>
@endforeach
@endif
</select>
</div>
</div>
{{-- 駐輪場(読み取り) --}}
<div class="field">
<label class="label">駐輪場</label>
<div class="input"><input type="text" class="form-control" value="{{ $parkName }}" readonly></div>
</div>
{{-- 駐輪場ID --}}
<div class="field">
<label class="label">駐輪場ID</label>
<div class="input">
<select name="park_id" class="form-control">
<option value="">選択してください</option>
@if(!empty($parkOptions))
@foreach($parkOptions as $k=>$v)
<option value="{{ $k }}" {{ (string)old('park_id', $row->park_id ?? '')===(string)$k?'selected':'' }}>
{{ $v }}
</option>
@endforeach
@endif
</select>
</div>
</div>
{{-- 駐輪場所ID --}}
<div class="field">
<label class="label">駐輪場所ID</label>
<div class="input">
<select name="price_parkplaceid" class="form-control">
<option value="">選択してください</option>
@if(!empty($parkplaceOptions))
@foreach($parkplaceOptions as $k=>$v)
<option value="{{ $k }}" {{ (string)old('price_parkplaceid', $row->price_parkplaceid ?? '')===(string)$k?'selected':'' }}>
{{ $v }}
</option>
@endforeach
@endif
</select>
</div>
</div>
{{-- 車種区分ID --}}
<div class="field">
<label class="label">車種区分ID</label>
<div class="input">
<select name="psection_id" class="form-control">
<option value="">選択してください</option>
@if(!empty($psectionOptions))
@foreach($psectionOptions as $k=>$v)
<option value="{{ $k }}" {{ (string)old('psection_id', $row->psection_id ?? '')===(string)$k?'selected':'' }}>
{{ $v }}
</option>
@endforeach
@endif
</select>
</div>
</div>
{{-- 駐輪分類ID --}}
<div class="field">
<label class="label">駐輪分類ID</label>
<div class="input">
<select name="ptype_id" class="form-control">
<option value="">選択してください</option>
@if(!empty($ptypeOptions))
@foreach($ptypeOptions as $k=>$v)
<option value="{{ $k }}" {{ (string)old('ptype_id', $row->ptype_id ?? '')===(string)$k?'selected':'' }}>
{{ $v }}
</option>
@endforeach
@endif
</select>
</div>
</div>
</div>
{{-- 右カラム(目标图顺序) --}}
<div class="col-lg-6">
{{-- 減免措置 --}}
<div class="field">
<label class="label">減免措置</label>
<div class="input">
@php $reduction = old('reduction', $row->reduction ?? ''); @endphp
<label class="mr-3"><input type="radio" name="reduction" value="1" {{ (string)$reduction==='1'?'checked':'' }}> あり</label>
<label><input type="radio" name="reduction" value="0" {{ (string)$reduction==='0'?'checked':'' }}> なし</label>
</div>
</div>
{{-- 自動リマインド日 --}}
<div class="field">
<label class="label">自動リマインド日</label>
<div class="input">
<input type="text" name="auto_remind_date" class="form-control" placeholder="yyyy/mm/dd"
value="{{ old('auto_remind_date', $row->auto_remind_date ?? '') }}">
</div>
</div>
{{-- 手動リマインド日 --}}
<div class="field">
<label class="label">手動リマインド日</label>
<div class="input">
<input type="text" name="manual_remind_date" class="form-control" placeholder="yyyy/mm/dd"
value="{{ old('manual_remind_date', $row->manual_remind_date ?? '') }}">
</div>
</div>
{{-- 800M以内フラグ --}}
<div class="field">
<label class="label">800M以内フラグ</label>
<div class="input">
@php $m800 = old('within_800m_flag', $row->within_800m_flag ?? ''); @endphp
<label class="mr-3"><input type="radio" name="within_800m_flag" value="1" {{ (string)$m800==='1'?'checked':'' }}> M以内</label>
<label><input type="radio" name="within_800m_flag" value="0" {{ (string)$m800==='0'?'checked':'' }}> M以内ではない</label>
</div>
</div>
{{-- 解約日 --}}
<div class="field">
<label class="label">解約日</label>
<div class="input">
<input type="text" name="contract_cancelday" class="form-control" placeholder="yyyy/mm/dd"
value="{{ old('contract_cancelday', $row->contract_cancelday ?? '') }}">
</div>
</div>
{{-- 有効フラグ --}}
<div class="field">
<label class="label">有効フラグ</label>
<div class="input">
@php $valid = old('valid_flag', $row->valid_flag ?? ''); @endphp
<label class="mr-3"><input type="radio" name="valid_flag" value="1" {{ (string)$valid==='1'?'checked':'' }}> 有効</label>
<label><input type="radio" name="valid_flag" value="0" {{ (string)$valid==='0'?'checked':'' }}> 無効</label>
</div>
</div>
{{-- 空き待ちメール送信日時 --}}
<div class="field">
<label class="label">空き待ちメール送信日時</label>
<div class="input">
<input type="text" name="mail_sent_at" class="form-control" placeholder="yyyy/mm/dd hh:mm:ss"
value="{{ old('mail_sent_at', $row->mail_sent_at ?? '') }}">
</div>
</div>
{{-- 手動通知 --}}
<div class="field">
<label class="label">手動通知</label>
<div class="input">
@php $mnotice = old('manual_notice', $row->manual_notice ?? ''); @endphp
<label class="mr-3"><input type="radio" name="manual_notice" value="0" {{ (string)$mnotice==='0'?'checked':'' }}> 手動通知</label>
<label><input type="radio" name="manual_notice" value="1" {{ (string)$mnotice==='1'?'checked':'' }}> メール通知</label>
</div>
</div>
{{-- 手動通知方法 --}}
<div class="field">
<label class="label">手動通知方法</label>
<div class="input">
@php $mhow = old('manual_notice_method', $row->manual_notice_method ?? ''); @endphp
<label class="mr-3"><input type="radio" name="manual_notice_method" value="tel" {{ $mhow==='tel'?'checked':'' }}> 電話</label>
<label><input type="radio" name="manual_notice_method" value="post" {{ $mhow==='post'?'checked':'' }}> 郵送</label>
<div class="help-text mt-1"> 必要に応じて選択肢は調整してください。</div>
</div>
</div>
{{-- 空き待ち順 --}}
<div class="field">
<label class="label">空き待ち順</label>
<div class="input">
<input type="number" name="waitlist_order" class="form-control" min="0" step="1"
value="{{ old('waitlist_order', $row->waitlist_order ?? '') }}">
</div>
</div>
</div>
</div>
</div>
{{-- 下部操作(保留:目标图底部有登録/削除) --}}
<div class="card-footer d-flex justify-content-start">
<button type="submit" class="btn btn-success">登録</button>
<button type="button" id="btnDeleteBottom" class="btn btn-danger ml-2">削除</button>
<a href="{{ route('reserves') }}" class="btn btn-default ml-2">戻る</a>
</div>
</form>
{{-- 削除POSTconfirmed + ids[] --}}
<form id="del-form" method="post" action="{{ route('reserves_delete') }}" style="display:none;">
@csrf
<input type="hidden" name="confirmed" value="1">
<input type="hidden" name="ids[]" value="{{ $row->reserve_id }}">
</form>
</div>
</div>
</section>
</div>
<script>
(function(){
function del(){ if(confirm('この予約を削除します。よろしいですか?')) document.getElementById('del-form').submit(); }
var t=document.getElementById('btnDeleteTop'), b=document.getElementById('btnDeleteBottom');
if(t) t.addEventListener('click', del);
if(b) b.addEventListener('click', del);
})();
</script>
@endsection

View File

@ -0,0 +1,263 @@
@extends('layouts.app')
@section('title', '定期予約マスタ')
@section('content')
<style>
/* 画面全体のフォント/サイズを統一(やや小さめ) */
.rv-page,
.rv-page .card,
.rv-page .form-control,
.rv-page .btn,
.rv-page table,
.rv-page .breadcrumb {
font-family: "Noto Sans JP","Hiragino Kaku Gothic ProN","Meiryo",system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
font-size: 13px;
line-height: 1.45;
}
/* フィルター1行左ラベル右入力、を縦に積む */
.rv-filter .field{display:flex;align-items:center;margin-bottom:.6rem;}
.rv-filter .label{flex:0 0 170px;margin:0;color:#333;font-weight:600;white-space:nowrap;}
.rv-filter .input{flex:1 1 auto;min-width:220px;}
.rv-filter .form-control{height:calc(2.0rem + 2px);padding:.25rem .5rem;}
.rv-filter .inline-range{display:flex;gap:.5rem;align-items:center;}
.rv-filter .tilde{color:#666;}
/* 一覧テーブル:斑馬(ゼブラ)無し、やや詰め気味 */
.rv-table th,.rv-table td{padding:.35rem .5rem;font-size:12px;}
.rv-table thead th{white-space:nowrap;background:#eeeeee;} /* ← 表頭:灰色 */
.card .card-header{background:#f5f5f5;} /* ← カード見出しも淡いグレー */
/* ツールバー:左にボタン群、右にページャ */
.rv-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;}
.rv-toolbar .btn+.btn{margin-left:.4rem;}
/* 操作セルの背景色(定期契約マスタと同じ雰囲気) */
.op-cell{background:#faebd7;}
</style>
<div class="rv-page">
{{-- パンくず・ヘッダ --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">定期予約マスタ</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item active">定期予約マスタ</li>
</ol>
</div>
</div>
@if(session('success'))
<div class="alert alert-success py-2 px-3 my-2">{{ session('success') }}</div>
@endif
@if($errors->any())
<div class="alert alert-danger py-2 px-3 my-2">
<ul class="mb-0">
@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach
</ul>
</div>
@endif
<p class="text-muted mb-0">※この画面では予約情報の検索・一括削除が行えます。</p>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 絞り込みフィルター(ここは前回どおり。必要に応じて調整可) --}}
<div class="card rv-filter">
<div class="card-header"><h3 class="card-title">絞り込みフィルター</h3></div>
<div class="card-body">
<form action="{{ route('reserves') }}" method="post" id="filter-form">
@csrf
<input type="hidden" name="sort" id="sort" value="{{ $sort }}">
<input type="hidden" name="sort_type" id="sort_type" value="{{ $sort_type }}">
<div class="row">
<div class="col-lg-6">
<div class="field">
<label class="label">利用者ID</label>
<div class="input">
<input type="text" class="form-control" name="user_id"
value="{{ $user_id ?? '' }}" placeholder="123456">
</div>
</div>
<div class="field">
<label class="label">有効フラグ</label>
<div class="input">
<select name="valid_flag" class="form-control">
<option value="">全て</option>
<option value="1" {{ (isset($valid_flag) && (string)$valid_flag==='1')?'selected':'' }}>有効</option>
<option value="0" {{ (isset($valid_flag) && (string)$valid_flag==='0')?'selected':'' }}>無効</option>
</select>
</div>
</div>
<div class="field">
<label class="label">メール送信日時</label>
<div class="input inline-range">
<input type="datetime-local" class="form-control" name="mail_sent_from"
value="{{ $mail_sent_from ?? '' }}">
<span class="tilde"></span>
<input type="datetime-local" class="form-control" name="mail_sent_to"
value="{{ $mail_sent_to ?? '' }}">
</div>
</div>
</div>
<div class="col-lg-6">
<div class="field">
<label class="label">駐輪場</label>
<div class="input">
<select name="park_id" class="form-control">
<option value="">全て</option>
@if(!empty($parkOptions) && is_iterable($parkOptions))
@foreach($parkOptions as $pid => $pname)
<option value="{{ $pid }}" {{ (isset($park_id) && (string)$park_id===(string)$pid)?'selected':'' }}>
{{ $pname }}
</option>
@endforeach
@endif
</select>
</div>
</div>
</div>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-default">絞り込み</button>
<a href="{{ route('reserves') }}" class="btn btn-default">解除</a>
</div>
</form>
</div>
</div>
{{-- ツールバーボタン群、右ページャCSV出力→削除 --}}
<div class="rv-toolbar mb-2">
<div class="left">
<a href="{{ route('reserves_add') }}" class="btn btn-sm btn-default">新規</a>
<button type="button" class="btn btn-sm btn-default" id="btnBulkDel">削除</button>
</div>
<div class="right">
{{ $list->appends(['sort'=>$sort,'sort_type'=>$sort_type])->links('pagination') }}
</div>
</div>
{{-- 一覧テーブル(先頭列の並び替えを削除/操作列にチェック+編集) --}}
<div class="card">
<form id="bulkDeleteForm" method="post" action="{{ route('reserves_delete') }}">
@csrf
<input type="hidden" name="confirmed" value="1">
<div class="table-responsive">
<table class="table table-bordered table-hover rv-table mb-0 text-nowrap">
<thead>
<tr>
{{-- 操作(全選択チェック+編集)※表頭は灰色 --}}
<th style="width:140px;">
<input type="checkbox" id="chkAll">
<span class="ml-1"></span>
</th>
{{-- 要求どおりの見出し(順番も完全一致) --}}
<th>定期予約ID</th>
<th>定期契約ID</th>
<th>定期契約日時</th>
<th>利用者分類ID</th>
<th>利用者ID</th>
<th>予約日時</th>
<th>駐輪場ID</th>
<th>駐輪場所ID</th>
<th>車種区分ID</th>
<th>駐輪分類ID</th>
<th>減免措置</th>
<th>自動リマインド日</th>
<th>手動リマインド日</th>
<th>800M以内フラグ</th>
<th>解約日</th>
<th>有効フラグ</th>
<th>メール送信日時</th>
<th>手動通知</th>
<th>手動通知方法</th>
<th>空き待ち順</th>
</tr>
</thead>
<tbody>
@foreach($list as $row)
<tr>
{{-- 操作セル--}}
<td class="op-cell">
<div class="d-flex align-items-center">
<input type="checkbox" class="mr-2 chkRow" name="ids[]" value="{{ $row->reserve_id }}">
<a href="{{ route('reserves_edit', ['reserve_id' => $row->reserve_id]) }}"
class="btn btn-sm btn-default">編集</a>
</div>
</td>
{{-- データ列(存在しないカラムは空文字で安全に表示) --}}
<td class="text-right">{{ $row->reserve_id }}</td> {{-- 定期予約ID --}}
<td class="text-right">{{ $row->contract_id ?? '' }}</td> {{-- 定期契約ID --}}
<td>{{ $row->contract_created_at ?? '' }}</td> {{-- 定期契約日時 --}}
<td class="text-right">{{ $row->user_categoryid ?? '' }}</td> {{-- 利用者分類ID --}}
<td class="text-right">{{ $row->user_id }}</td> {{-- 利用者ID --}}
<td>{{ $row->reserve_date ?? '' }}</td> {{-- 予約日時 --}}
<td class="text-right">{{ $row->park_id ?? '' }}</td> {{-- 駐輪場ID --}}
<td class="text-right">{{ $row->price_parkplaceid ?? '' }}</td> {{-- 駐輪場所ID --}}
<td class="text-right">{{ $row->psection_id ?? '' }}</td> {{-- 車種区分ID --}}
<td class="text-right">{{ $row->ptype_id ?? '' }}</td> {{-- 駐輪分類ID --}}
<td>{{ $row->reduction ?? '' }}</td> {{-- 減免措置 --}}
<td>{{ $row->auto_remind_date ?? '' }}</td> {{-- 自動リマインド日 --}}
<td>{{ $row->manual_remind_date ?? '' }}</td> {{-- 手動リマインド日 --}}
<td>{{ isset($row->within_800m_flag) ? (($row->within_800m_flag)?'有':'無') : '' }}</td> {{-- 800M以内フラグ --}}
<td>{{ $row->contract_cancelday ?? '' }}</td> {{-- 解約日 --}}
<td>{{ isset($row->valid_flag) ? (($row->valid_flag)?'有効':'無効') : '' }}</td> {{-- 有効フラグ --}}
<td>{{ $row->mail_sent_at ?? '' }}</td> {{-- メール送信日時 --}}
<td>{{ isset($row->manual_notice) ? (($row->manual_notice)?'有':'無') : '' }}</td> {{-- 手動通知 --}}
<td>{{ $row->manual_notice_method ?? '' }}</td> {{-- 手動通知方法 --}}
<td class="text-right">{{ $row->waitlist_order ?? '' }}</td> {{-- 空き待ち順 --}}
</tr>
@endforeach
</tbody>
</table>
</div>
</form>
</div>
{{-- 下側ページャ(右寄せ) --}}
<div class="d-flex justify-content-end mt-2">
{{ $list->appends(['sort'=>$sort,'sort_type'=>$sort_type])->links('pagination') }}
</div>
</div>
</section>
</div>
{{-- 一括削除のフロント処理jQuery不要 --}}
<script>
(function(){
// 全選択チェック
var chkAll = document.getElementById('chkAll');
var chks = document.getElementsByClassName('chkRow');
if (chkAll) {
chkAll.addEventListener('change', function(){
Array.prototype.forEach.call(chks, function(c){ c.checked = chkAll.checked; });
});
}
// 一括削除ボタン
var btn = document.getElementById('btnBulkDel');
var form = document.getElementById('bulkDeleteForm');
if (btn && form) {
btn.addEventListener('click', function(){
var any = false;
Array.prototype.forEach.call(chks, function(c){ if (c.checked) any = true; });
if (!any) { alert('削除対象の行を選択してください。'); return; }
if (confirm('選択した予約を削除します。よろしいですか?')) {
form.submit();
}
});
}
})();
</script>
@endsection

View File

@ -0,0 +1,281 @@
@extends('layouts.app')
@section('title', '更新予定者一覧')
@section('content')
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6">
<h1 class="m-0 text-dark">更新予定者一覧</h1>
</div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ url('/home') }}">ホーム</a></li>
<li class="breadcrumb-item active">更新予定者一覧</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- 絞り込みフィルター左右2カラム、ラベル3入力9で整列 --}}
<form method="GET" action="{{ route('update_candidate') }}" class="mb-3" id="filter-form">
<div class="card p-3">
<h6 class="mb-3">絞り込みフィルター</h6>
<div class="row">
{{-- 左カラム --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">駐輪場</label>
<div class="col-sm-9">
@isset($parks)
<select name="park_id" class="form-control">
<option value="">全て</option>
@foreach($parks as $p)
<option value="{{ $p->park_id }}" {{ (string)request('park_id')===(string)$p->park_id ? 'selected' : '' }}>
{{ $p->park_name }}
</option>
@endforeach
</select>
@else
<input type="text" name="park_name" value="{{ request('park_name') }}" class="form-control">
@endisset
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者ID</label>
<div class="col-sm-9">
<input type="text" name="user_id" value="{{ request('user_id') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">利用者分類</label>
<div class="col-sm-9">
<input type="text" name="user_categoryid" value="{{ request('user_categoryid') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグシリアル64進</label>
<div class="col-sm-9">
<input type="text" name="user_tag_serial_64" value="{{ request('user_tag_serial_64') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">有効期限</label>
<div class="col-sm-9">
<input type="date" name="contract_periode" value="{{ request('contract_periode') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">対象月</label>
<div class="col-sm-9 d-flex align-items-center">
@php
$target_month = request('target_month', 'this');
@endphp
<div class="form-check mr-3">
<input class="form-check-input" type="radio" name="target_month" id="last_month" value="last" {{ $target_month === 'last' ? 'checked' : '' }}>
<label class="form-check-label" for="last_month">先月</label>
</div>
<div class="form-check mr-3">
<input class="form-check-input" type="radio" name="target_month" id="this_month" value="this" {{ $target_month === 'this' ? 'checked' : '' }}>
<label class="form-check-label" for="this_month">今月</label>
</div>
<div class="form-check mr-3">
<input class="form-check-input" type="radio" name="target_month" id="next_month" value="next" {{ $target_month === 'next' ? 'checked' : '' }}>
<label class="form-check-label" for="next_month">来月</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="target_month" id="after_2_month" value="after2" {{ $target_month === 'after2' ? 'checked' : '' }}>
<label class="form-check-label" for="after_2_month">2か月後</label>
</div>
</div>
</div>
</div>
{{-- 右カラム --}}
<div class="col-md-6">
<div class="form-group row">
<label class="col-sm-3 col-form-label">フリガナ</label>
<div class="col-sm-9">
<input type="text" name="user_phonetic" value="{{ request('user_phonetic') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">電話番号</label>
<div class="col-sm-9">
<input type="text" name="user_mobile" value="{{ request('user_mobile') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">メールアドレス</label>
<div class="col-sm-9">
<input type="text" name="user_primemail" value="{{ request('user_primemail') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">勤務先</label>
<div class="col-sm-9">
<input type="text" name="user_workplace" value="{{ request('user_workplace') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">学校</label>
<div class="col-sm-9">
<input type="text" name="user_school" value="{{ request('user_school') }}" class="form-control">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">タグ・QR</label>
<div class="col-sm-9">
<select name="tag_qr_flag" class="form-control">
<option value="" {{ request('tag_qr_flag')==='' ? 'selected' : '' }}>全て</option>
<option value="1" {{ request('tag_qr_flag')==='1' ? 'selected' : '' }}>QR</option>
<option value="0" {{ request('tag_qr_flag')==='0' ? 'selected' : '' }}>タグ</option>
</select>
</div>
</div>
</div>
</div>
<div class="mt-2">
<button type="submit" class="btn btn-default">絞り込み</button>
<a href="{{ route('update_candidate') }}" class="btn btn-default">解除</a>
</div>
</div>
</form>
{{-- 一覧テーブル(非折返し表示/表頭グレー) --}}
<div class="table-responsive">
<table class="table table-bordered table-hover table-sm rv-table text-nowrap">
<thead>
<tr>
<th>利用者ID</th>
<th>氏名</th>
<th>フリガナ</th>
<th>
<a href="{{ request()->fullUrlWithQuery([
'sort' => 'contract_id',
'sort_type' => (request('sort') === 'contract_id' && request('sort_type') === 'asc') ? 'desc' : 'asc'
]) }}">
定期契約ID
@if(request('sort') === 'contract_id')
@if(request('sort_type') === 'asc') @else @endif
@endif
</a>
</th>
<th>タグ・QR</th>
<th>駐輪場</th>
<th>車種区分</th>
<th>減免措置</th>
<th>利用者分類1</th>
<th>利用者分類2</th>
<th>利用者分類3</th>
<th>携帯電話番号</th>
<th>自宅電話番号</th>
<th>生年月日</th>
<th>性別</th>
<th>居住所:郵便番号</th>
<th>居住所:都道府県</th>
<th>居住所:市区群</th>
<th>居住所:住所</th>
<th>関連住所:郵便番号</th>
<th>関連住所:都道府県</th>
<th>関連住所:市区群</th>
<th>関連住所:住所</th>
<th>契約日</th>
<th>利用期間</th>
<th>有効期間</th>
<th>定期券区分</th>
<th>勤務先名</th>
<th>学校</th>
<th>卒業予定</th>
<th>シール発行回数</th>
<th>防犯登録</th>
<th>備考</th>
<th>授受フラグ</th>
<th>授受日時</th>
</tr>
</thead>
<tbody>
@forelse ($rows as $row)
<tr>
<td>{{ $row->user_id }}</td>
<td>{{ $row->user_name }}</td>
<td>{{ $row->user_phonetic }}</td>
<td>{{ $row->contract_id }}</td>
<td>{{ $row->tag_qr_flag ? 'QR' : 'タグ' }}</td>
<td>{{ $row->park_name }}</td>
<td>{{ $row->vehicle_type ?? '' }}</td>
<td>{{ $row->user_reduction ?? '' }}</td>
<td>{{ $row->user_category1 ?? '' }}</td>
<td>{{ $row->user_category2 ?? '' }}</td>
<td>{{ $row->user_category3 ?? '' }}</td>
<td>{{ $row->user_mobile }}</td>
<td>{{ $row->user_homephone }}</td>
<td>{{ $row->user_birthdate }}</td>
<td>{{ $row->user_gender }}</td>
<td>{{ $row->user_regident_zip }}</td>
<td>{{ $row->user_regident_pre }}</td>
<td>{{ $row->user_regident_city }}</td>
<td>{{ $row->user_regident_add }}</td>
<td>{{ $row->user_relate_zip }}</td>
<td>{{ $row->user_relate_pre }}</td>
<td>{{ $row->user_relate_city }}</td>
<td>{{ $row->user_relate_add }}</td>
<td>{{ $row->contract_created_at }}</td>
<td>{{ $row->contract_periods }}</td>
<td>{{ $row->contract_periode }}</td>
<td>{{ $row->ticket_type ?? '' }}</td>
<td>{{ $row->user_workplace }}</td>
<td>{{ $row->user_school }}</td>
<td>{{ $row->user_graduate }}</td>
<td>{{ $row->seal_issue_count ?? '' }}</td>
<td>{{ $row->crime_prevention ?? '' }}</td>
<td>{{ $row->user_remarks }}</td>
{{-- 授受フラグ/授受日時(カラム名不確定のため安全アクセス) --}}
<td>
{{ $row->receive_flag ?? $row->handover_flag ?? $row->transfer_flag ?? '' }}
</td>
<td>
{{ $row->receive_datetime ?? $row->handover_datetime ?? $row->transfer_datetime ?? '' }}
</td>
</tr>
@empty
<tr>
<td colspan="35" class="text-center">データがありません。</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-3">
{{ $rows->appends(request()->except('page'))->links('pagination::bootstrap-4') }}
</div>
</div>
</section>
{{-- 画面用スタイル(表頭をグレー、明朝は非推奨・可読優先/データ折返し禁止) --}}
<style>
.rv-table thead th{
background:#eeeeee;
white-space:nowrap;
vertical-align:middle;
}
.rv-table tbody tr{ background:#fff; }
</style>
@endsection

View File

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
@ -33,11 +34,12 @@
<link rel="stylesheet" href="{{ asset('assets/css/style.css') }}"> <link rel="stylesheet" href="{{ asset('assets/css/style.css') }}">
<!-- Styles --> <!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet"> <link href="{{ asset('assets/css/style.css') }}" rel="stylesheet">
</head> </head>
<body class="hold-transition sidebar-mini"> <body class="hold-transition sidebar-mini">
<div class="wrapper"> <div class="wrapper">
<!-- Navbar --> <!-- Navbar -->
<nav class="main-header navbar navbar-expand bg-white navbar-light border-bottom"> <nav class="main-header navbar navbar-expand bg-white navbar-light border-bottom">
<!-- Left navbar links --> <!-- Left navbar links -->
@ -69,13 +71,17 @@
<!-- Messages Dropdown Menu --> <!-- Messages Dropdown Menu -->
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link text-danger" data-toggle="dropdown" href="#"> <a class="nav-link text-danger" data-toggle="dropdown" href="#">
<i class="fa fa-exclamation-circle"></i><span class="d-none d-md-inline"> {{__('ハード異常:')}}</span> {{__(':stt件',['stt'=>1])}} <small class="d-none d-md-inline">{{__('最新:date',['date'=>'2018/09/01 15:00'])}} </small> <i class="fa fa-exclamation-circle"></i><span class="d-none d-md-inline">
{{__('ハード異常:')}}</span> {{__(':stt件', ['stt' => 1])}} <small
class="d-none d-md-inline">{{__('最新:date', ['date' => '2018/09/01 15:00'])}} </small>
</a> </a>
</li> </li>
<!-- Notifications Dropdown Menu --> <!-- Notifications Dropdown Menu -->
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#"> <a class="nav-link" data-toggle="dropdown" href="#">
<i class="fa fa-bell-o"></i><span class="d-none d-md-inline"> {{__('タスク:')}} </span> {{__(':stt件',['stt'=>5])}} <small class="d-none d-md-inline">{{__('最新:date',['date'=>'2018/09/01 15:00'])}}</small> <i class="fa fa-bell-o"></i><span class="d-none d-md-inline"> {{__('タスク:')}} </span>
{{__(':stt件', ['stt' => 5])}} <small
class="d-none d-md-inline">{{__('最新:date', ['date' => '2018/09/01 15:00'])}}</small>
</a> </a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<span class="dropdown-header">5 件のタスクが未完了です。</span> <span class="dropdown-header">5 件のタスクが未完了です。</span>
@ -119,8 +125,7 @@
<aside class="main-sidebar sidebar-dark-primary bg-success elevation-4"> <aside class="main-sidebar sidebar-dark-primary bg-success elevation-4">
<!-- Brand Logo --> <!-- Brand Logo -->
<a href="/home" class="brand-link"> <a href="/home" class="brand-link">
<img src="{{asset('assets/img/so-rin_logo.png')}}" alt="Logo" class="brand-image" <img src="{{asset('assets/img/so-rin_logo.png')}}" alt="Logo" class="brand-image" style="opacity: .8">
style="opacity: .8">
<span class="brand-text font-weight-light">So-Manager</span> <span class="brand-text font-weight-light">So-Manager</span>
</a> </a>
@ -157,7 +162,8 @@
<!-- Sidebar Menu --> <!-- Sidebar Menu -->
<nav class="mt-2"> <nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false"> <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu"
data-accordion="false">
<!-- Add icons to the links using the .nav-icon class <!-- Add icons to the links using the .nav-icon class
with font-awesome or any other icon font library --> with font-awesome or any other icon font library -->
<li class="nav-item"> <li class="nav-item">
@ -169,8 +175,19 @@
</p> </p>
</a> </a>
</li> </li>
<li class="nav-item has-treeview">
<a href="#" class="nav-link"> <!-- OU START -->
@php
// 一般ウェブ管理下的路由名列表(按你项目实际替换)
$webRoutes = [
'news', // 最新ニュース登録
// 需要高亮/展开的其它路由继续加到这里
];
@endphp
<li
class="nav-item has-treeview @if(in_array(app('router')->currentRouteName(), $webRoutes)) menu-open @endif">
<a href="#"
class="nav-link @if(in_array(app('router')->currentRouteName(), $webRoutes)) active @endif">
<i class="nav-icon fa fa-dashboard"></i> <i class="nav-icon fa fa-dashboard"></i>
<p> <p>
一般ウェブ管理 一般ウェブ管理
@ -179,27 +196,151 @@
</a> </a>
<ul class="nav nav-treeview"> <ul class="nav nav-treeview">
<li class="nav-item"> <li class="nav-item">
<a href="./example.html" class="nav-link"> <a href="{{ route('news') }}"
class="nav-link @if(app('router')->currentRouteName() === 'news`') active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>下層メニュー1</p> <p>最新ニュース登録</p>
</a>
</li>
<li class="nav-item">
<a href="./example.html" class="nav-link">
<i class="fa fa-circle-o nav-icon"></i>
<p>下層メニュー2</p>
</a> </a>
</li> </li>
</ul> </ul>
</li> </li>
<li class="nav-item has-treeview">
<a href="#" class="nav-link "> @php
<i class="nav-icon fa fa-bicycle"></i> // 利用者マスタ分组:当当前路由名在这里时,展开&高亮
$userGroupRoutes = [
'users', // 利用者マスタ
'regularcontracts', // 定期契約マスタ
'reserves', // 定期予約マスタ
'usertypes', // 定期予約マスタ
];
@endphp
<li
class="nav-item has-treeview @if(in_array(app('router')->currentRouteName(), $userGroupRoutes)) menu-open @endif">
<a href="#"
class="nav-link @if(in_array(app('router')->currentRouteName(), $userGroupRoutes)) active @endif">
<i class="nav-icon fa fa-th"></i>
<p> <p>
駐輪管理 利用者マスタ
<i class="right fa fa-angle-down"></i> <i class="right fa fa-angle-down"></i>
</p> </p>
</a> </a>
<ul class="nav nav-treeview" @if(in_array(app('router')->currentRouteName(), $userGroupRoutes)) style="display: block;" @else style="display: none;" @endif>
<li class="nav-item">
<a href="{{ route('users') }}"
class="nav-link @if(app('router')->is('users')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>利用者マスタ</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('regularcontracts') }}"
class="nav-link @if(app('router')->is('regularcontracts')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>定期契約マスタ</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('reserves') }}"
class="nav-link @if(app('router')->is('reserves')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>定期予約マスタ</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('usertypes') }}"
class="nav-link @if(app('router')->is('usertypes')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>利用者分類マスタ</p>
</a>
</li>
</ul>
</li>
@php
// 駐輪管理下的路由名列表
$parkingRoutes = [
'periodical', // 定期利用・契約状況
'contractor', // 契約者一覧
'contractor_List', // 未更新者一覧
'update_candidate', // 更新予定者一覧
'reservation', // 予約者一覧
// 以后这里还可以继续加其它駐輪管理的路由
];
@endphp
<li
class="nav-item has-treeview @if(in_array(app('router')->currentRouteName(), $parkingRoutes)) menu-open @endif">
<a href="#"
class="nav-link @if(in_array(app('router')->currentRouteName(), $parkingRoutes)) active @endif">
<i class="nav-icon fa fa-repeat"></i>
<p>
定期駐輪管理
<i class="right fa fa-angle-down"></i>
</p>
</a>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="{{ route('periodical') }}"
class="nav-link @if(app('router')->currentRouteName() === 'periodical') active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>定期利用・契約状況</p>
</a>
</li>
</ul>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="{{ route('contractor') }}"
class="nav-link @if(app('router')->currentRouteName() === 'contractor') active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>契約者一覧</p>
</a>
</li>
</ul>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="{{ route('contractor_List') }}"
class="nav-link @if(app('router')->currentRouteName() === 'contractor_List') active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>未更新者一覧</p>
</a>
</li>
</ul>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="{{ route('update_candidate') }}"
class="nav-link @if(app('router')->currentRouteName() === 'update_candidate') active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>更新予定者一覧</p>
</a>
</li>
</ul>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="{{ route('reservation') }}"
class="nav-link @if(app('router')->currentRouteName() === 'reservation') active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>予約者一覧</p>
</a>
</li>
</ul>
</li>
<!-- OU END -->
<ul class="nav nav-treeview"> <ul class="nav nav-treeview">
<li class="nav-item"> <li class="nav-item">
<a href="#" class="nav-link"> <a href="#" class="nav-link">
@ -242,66 +383,23 @@
<a href="#" class="nav-link"> <a href="#" class="nav-link">
<i class="nav-icon fa fa-repeat"></i> <i class="nav-icon fa fa-repeat"></i>
<p> <p>
定期駐輪管理 駐輪管理
<i class="right fa fa-angle-down"></i> <i class="nav-icon fa fa-bicycle"></i>
</p> </p>
</a> </a>
<ul class="nav nav-treeview"> <ul class="nav nav-treeview">
{{--
Laravel 12移行時の定期駐輪管理メニュー項目
実装完了済み:区画別利用率状況
--}}
<li class="nav-item"> <li class="nav-item">
<a href="{{ route('using_status') }}" class="nav-link @if(request()->routeIs('using_status*')) active @endif"> <a href="./example.html" class="nav-link">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>区画別利用率状況</p> <p>下層メニュー1</p>
</a>
</li>
{{--
Laravel 12移行時に一時的にコメントアウト:他の機能は順次実装予定
<li class="nav-item">
<a href="{{ route('contractor') }}" class="nav-link @if(request()->routeIs('contractor*')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>契約者一覧</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ route('contractor_list') }}" class="nav-link @if(request()->routeIs('contractor_list*')) active @endif"> <a href="./example.html" class="nav-link">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>未更新者一覧</p> <p>下層メニュー2</p>
</a> </a>
</li> </li>
<li class="nav-item">
<a href="{{ route('update_candidate') }}" class="nav-link @if(request()->routeIs('update_candidate*')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>更新予定者一覧</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('reservation') }}" class="nav-link @if(request()->routeIs('reservation*')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>予約者一覧</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('personal') }}" class="nav-link @if(request()->routeIs('personal*')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>本人確認手動処理</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('refund_processing') }}" class="nav-link @if(request()->routeIs('refund_processing*')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>返金処理</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('periodical_usage') }}" class="nav-link @if(request()->routeIs('periodical_usage*')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>定期利用・契約状況</p>
</a>
</li>
--}}
</ul> </ul>
</li> </li>
<li class="nav-item has-treeview"> <li class="nav-item has-treeview">
@ -351,11 +449,8 @@
</ul> </ul>
</li> </li>
<?php $route = [ <?php $route = [
'users',
'opes', 'opes',
'regular_contracts',
'ptypes', 'ptypes',
'usertypes',
'prices', 'prices',
'parks', 'parks',
'managers', 'managers',
@ -365,60 +460,124 @@
'regular_types', 'regular_types',
'seals', 'seals',
'jurisdiction_parkings', 'jurisdiction_parkings',
];?> 'city',
<li class="nav-item has-treeview @if(in_array(app('router')->currentRouteName(),$route )) menu-open @endif"> 'pricelist',
<a href="#" class="nav-link @if(in_array(app('router')->currentRouteName(), $route)) active @endif"> 'prices',
'psection',
];?>
<li
class="nav-item has-treeview @if(in_array(app('router')->currentRouteName(), $route)) menu-open @endif">
<a href="#"
class="nav-link @if(in_array(app('router')->currentRouteName(), $route)) active @endif">
<i class="nav-icon fa fa-th"></i> <i class="nav-icon fa fa-th"></i>
<p> <p>
{{__("マスタ管理")}} {{__("マスタ管理")}}
<i class="right fa fa-angle-down"></i> <i class="right fa fa-angle-down"></i>
</p> </p>
</a> </a>
<ul class="nav nav-treeview" @if(in_array(app('router')->currentRouteName(), $route))
style="display: block;" @else style="display: none;" @endif>
<li class="nav-item">
<a href="{{route('parks')}}"
class="nav-link @if(app('router')->is('parks')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{__("駐輪場マスタ")}}</p>
</a>
</li>
<li class="nav-item">
<a href="{{route('city')}}"
class="nav-link @if(app('router')->is('city')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{__("市区マスタ")}}</p>
</a>
</li>
<li class="nav-item">
<a href="{{ route('pricelist') }}"
class="nav-link {{ app('router')->is('pricelist') ? 'active' : '' }}">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{ __("料金一覧表") }}</p>
</a>
</li>
<li class="nav-item">
<a href="{{route('prices')}}"
class="nav-link @if(app('router')->is('prices')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{__('駐輪場所、料金マスタ')}}</p>
</a>
</li>
<li class="nav-item">
<a href="{{route('psection')}}"
class="nav-link @if(app('router')->is('psection')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{__('車種区分マスタ')}}</p>
</a>
</li>
<li class="nav-item">
<a href="{{route('ptypes')}}"
class="nav-link @if(app('router')->is('ptypes')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{__('駐輪分類マスタ')}}</p>
</a>
</li>
</ul>
</li>
{{-- {{--
Laravel 12移行時に一時的にコメントアウトrouteが未定義のため Laravel 12移行時に一時的にコメントアウトrouteが未定義のため
<ul class="nav nav-treeview" style="display: block;"> <ul class="nav nav-treeview" style="display: block;">
<li class="nav-item"> <li class="nav-item">
<a href="{{route('users')}}" class="nav-link @if(app('router')->is('users')) active @endif"> <a href="{{route('users')}}"
class="nav-link @if(app('router')->is('users')) active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>{{__('利用者マスタ')}}</p> <p>{{__('利用者マスタ')}}</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{route('regular_contracts')}}" class="nav-link @if(app('router')->is('regular_contracts')) active @endif"> <a href="{{route('regular_contracts')}}"
class="nav-link @if(app('router')->is('regular_contracts')) active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>{{__('定期契約マスタ')}}</p> <p>{{__('定期契約マスタ')}}</p>
</a> </a>
</li> </li>
<li class="nav-item">
<a href="{{route('prices')}}" class="nav-link @if(app('router')->is('prices')) active @endif">
<i class="fa fa-circle-o nav-icon"></i>
<p>{{__('駐輪場所、料金マスタ')}}</p>
</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a href="{{route('opes')}}" class="nav-link @if(app('router')->is('opes')) active @endif"> <a href="{{route('opes')}}"
class="nav-link @if(app('router')->is('opes')) active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>{{__('オペレータマスタ')}}</p> <p>{{__('オペレータマスタ')}}</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{route('parks')}}" class="nav-link @if(app('router')->is('parks')) active @endif"> <a href="{{route('parks')}}"
class="nav-link @if(app('router')->is('parks')) active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>{{__("駐輪場マスタ")}}</p> <p>{{__("駐輪場マスタ")}}</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{route('settlement_transactions')}}" class="nav-link @if(app('router')->is('settlement_transactions')) active @endif"> <a href="{{route('settlement_transactions')}}"
class="nav-link @if(app('router')->is('settlement_transactions')) active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>{{__('決済トランザクション')}}</p> <p>{{__('決済トランザクション')}}</p>
</a> </a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a href="{{route('print_areas')}}" class="nav-link @if(app('router')->is('print_areas')) active @endif"> <a href="{{route('print_areas')}}"
class="nav-link @if(app('router')->is('print_areas')) active @endif">
<i class="fa fa-circle-o nav-icon"></i> <i class="fa fa-circle-o nav-icon"></i>
<p>{{__("シール印刷範囲マスタ")}}</p> <p>{{__("シール印刷範囲マスタ")}}</p>
</a> </a>
@ -433,7 +592,8 @@
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('ptypes')}}" class="nav-link @if(app('router')->is('ptypes')) active @endif">--}} {{--<a href="{{route('ptypes')}}"
class="nav-link @if(app('router')->is('ptypes')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__('駐輪分類マスタ')}}</p>--}} {{--<p>{{__('駐輪分類マスタ')}}</p>--}}
{{--</a>--}} {{--</a>--}}
@ -445,7 +605,8 @@
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('usertypes')}}" class="nav-link @if(app('router')->is('usertypes')) active @endif">--}} {{--<a href="{{route('usertypes')}}"
class="nav-link @if(app('router')->is('usertypes')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__('利用者分類マスタ')}}</p>--}} {{--<p>{{__('利用者分類マスタ')}}</p>--}}
{{--</a>--}} {{--</a>--}}
@ -469,7 +630,8 @@
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('managers')}}" class="nav-link @if(app('router')->is('managers')) active @endif">--}} {{--<a href="{{route('managers')}}"
class="nav-link @if(app('router')->is('managers')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__("駐車場管理者マスタ")}}</p>--}} {{--<p>{{__("駐車場管理者マスタ")}}</p>--}}
{{--</a>--}} {{--</a>--}}
@ -481,25 +643,29 @@
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('operator_ques')}}" class="nav-link @if(app('router')->is('operator_ques')) active @endif">--}} {{--<a href="{{route('operator_ques')}}"
class="nav-link @if(app('router')->is('operator_ques')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__("オペレータキュー")}}</p>--}} {{--<p>{{__("オペレータキュー")}}</p>--}}
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('regular_types')}}" class="nav-link @if(app('router')->is('regular_types')) active @endif">--}} {{--<a href="{{route('regular_types')}}"
class="nav-link @if(app('router')->is('regular_types')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__("定期種別マスタ")}}</p>--}} {{--<p>{{__("定期種別マスタ")}}</p>--}}
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('seals')}}" class="nav-link @if(app('router')->is('seals')) active @endif">--}} {{--<a href="{{route('seals')}}"
class="nav-link @if(app('router')->is('seals')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__("シール発行履歴")}}</p>--}} {{--<p>{{__("シール発行履歴")}}</p>--}}
{{--</a>--}} {{--</a>--}}
{{--</li>--}} {{--</li>--}}
{{--<li class="nav-item">--}} {{--<li class="nav-item">--}}
{{--<a href="{{route('jurisdiction_parkings')}}" class="nav-link @if(app('router')->is('jurisdiction_parkings')) active @endif">--}} {{--<a href="{{route('jurisdiction_parkings')}}"
class="nav-link @if(app('router')->is('jurisdiction_parkings')) active @endif">--}}
{{--<i class="fa fa-circle-o nav-icon"></i>--}} {{--<i class="fa fa-circle-o nav-icon"></i>--}}
{{--<p>{{__("管轄駐輪場")}}</p>--}} {{--<p>{{__("管轄駐輪場")}}</p>--}}
{{--</a>--}} {{--</a>--}}
@ -526,9 +692,12 @@
</div> </div>
<!-- /.content-wrapper --> <!-- /.content-wrapper -->
@stack('scripts')
<!-- Main Footer --> <!-- Main Footer -->
<footer class="main-footer"> <footer class="main-footer">
<strong>Copyright &copy; 2018 <a href="./index2.html">So-Manager for back office by so-rin Co.,Ltd.</a></strong> All rights reserved. <strong>Copyright &copy; 2018 <a href="./index2.html">So-Manager for back office by so-rin
Co.,Ltd.</a></strong> All rights reserved.
</footer> </footer>
<!-- Control Sidebar --> <!-- Control Sidebar -->
@ -536,41 +705,41 @@
<!-- Control sidebar content goes here --> <!-- Control sidebar content goes here -->
</aside> </aside>
<!-- /.control-sidebar --> <!-- /.control-sidebar -->
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
<!-- jQuery --> <!-- jQuery -->
<script src="{{ asset('plugins/jquery/jquery.min.js') }}"></script> <script src="{{ asset('plugins/jquery/jquery.min.js') }}"></script>
<!-- Bootstrap 4 --> <!-- Bootstrap 4 -->
<script src="{{ asset('plugins/bootstrap/js/bootstrap.bundle.min.js') }}"></script> <script src="{{ asset('plugins/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<!-- Select2 --> <!-- Select2 -->
<script src="{{ asset('plugins/select2/select2.full.min.js') }}"></script> <script src="{{ asset('plugins/select2/select2.full.min.js') }}"></script>
<!-- InputMask --> <!-- InputMask -->
<script src="{{ asset('plugins/input-mask/jquery.inputmask.js') }}"></script> <script src="{{ asset('plugins/input-mask/jquery.inputmask.js') }}"></script>
<script src="{{ asset('plugins/input-mask/jquery.inputmask.date.extensions.js') }}"></script> <script src="{{ asset('plugins/input-mask/jquery.inputmask.date.extensions.js') }}"></script>
<script src="{{ asset('plugins/input-mask/jquery.inputmask.extensions.js') }}"></script> <script src="{{ asset('plugins/input-mask/jquery.inputmask.extensions.js') }}"></script>
<!-- date-range-picker --> <!-- date-range-picker -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<script src="{{ asset('plugins/daterangepicker/daterangepicker.js') }}"></script> <script src="{{ asset('plugins/daterangepicker/daterangepicker.js') }}"></script>
<script src="{{ asset('plugins/datepicker/bootstrap-datepicker.js') }}"></script> <script src="{{ asset('plugins/datepicker/bootstrap-datepicker.js') }}"></script>
<script src="{{ asset('plugins/datepicker/locales/bootstrap-datepicker.ja.js') }}"></script> <script src="{{ asset('plugins/datepicker/locales/bootstrap-datepicker.ja.js') }}"></script>
<!-- bootstrap color picker --> <!-- bootstrap color picker -->
<script src="{{ asset('plugins/colorpicker/bootstrap-colorpicker.min.js') }}"></script> <script src="{{ asset('plugins/colorpicker/bootstrap-colorpicker.min.js') }}"></script>
<!-- bootstrap time picker --> <!-- bootstrap time picker -->
<script src="{{ asset('plugins/timepicker/bootstrap-timepicker.min.js') }}"></script> <script src="{{ asset('plugins/timepicker/bootstrap-timepicker.min.js') }}"></script>
<!-- SlimScroll 1.3.0 --> <!-- SlimScroll 1.3.0 -->
<script src="{{ asset('plugins/slimScroll/jquery.slimscroll.min.js') }}"></script> <script src="{{ asset('plugins/slimScroll/jquery.slimscroll.min.js') }}"></script>
<!-- iCheck 1.0.1 --> <!-- iCheck 1.0.1 -->
<script src="{{ asset('plugins/iCheck/icheck.min.js') }}"></script> <script src="{{ asset('plugins/iCheck/icheck.min.js') }}"></script>
<!-- FastClick --> <!-- FastClick -->
<script src="{{ asset('plugins/fastclick/fastclick.js') }}"></script> <script src="{{ asset('plugins/fastclick/fastclick.js') }}"></script>
<!-- AdminLTE App --> <!-- AdminLTE App -->
<script src="{{ asset('dist/js/adminlte.min.js') }}"></script> <script src="{{ asset('dist/js/adminlte.min.js') }}"></script>
<!-- AdminLTE for demo purposes --> <!-- AdminLTE for demo purposes -->
<script src="{{ asset('dist/js/demo.js') }}"></script> <script src="{{ asset('dist/js/demo.js') }}"></script>
<!-- Page script --> <!-- Page script -->
<script> <script>
$(function () { $(function () {
//Initialize Select2 Elements //Initialize Select2 Elements
$('.select2').select2(); $('.select2').select2();
@ -586,23 +755,23 @@
$('#reservation').daterangepicker() $('#reservation').daterangepicker()
//Date range picker with time picker //Date range picker with time picker
$('#reservationtime').daterangepicker({ $('#reservationtime').daterangepicker({
timePicker : true, timePicker: true,
timePickerIncrement: 30, timePickerIncrement: 30,
format : 'MM/DD/YYYY h:mm A' format: 'MM/DD/YYYY h:mm A'
}) })
//Date range as a button //Date range as a button
$('#daterange-btn').daterangepicker( $('#daterange-btn').daterangepicker(
{ {
ranges : { ranges: {
'今日' : [moment(), moment()], '今日': [moment(), moment()],
'昨日' : [moment().subtract(1, 'days'), moment().subtract(1, 'days')], '昨日': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'最新の1週間' : [moment().subtract(6, 'days'), moment()], '最新の1週間': [moment().subtract(6, 'days'), moment()],
'最新の30日': [moment().subtract(29, 'days'), moment()], '最新の30日': [moment().subtract(29, 'days'), moment()],
'今月' : [moment().startOf('month'), moment().endOf('month')], '今月': [moment().startOf('month'), moment().endOf('month')],
'先月' : [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')] '先月': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}, },
startDate: moment().subtract(29, 'days'), startDate: moment().subtract(29, 'days'),
endDate : moment() endDate: moment()
}, },
function (start, end) { function (start, end) {
$('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY')) $('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'))
@ -612,17 +781,17 @@
//iCheck for checkbox and radio inputs //iCheck for checkbox and radio inputs
$('input[type="checkbox"].minimal, input[type="radio"].minimal').iCheck({ $('input[type="checkbox"].minimal, input[type="radio"].minimal').iCheck({
checkboxClass: 'icheckbox_minimal-blue', checkboxClass: 'icheckbox_minimal-blue',
radioClass : 'iradio_minimal-blue' radioClass: 'iradio_minimal-blue'
}) })
//Red color scheme for iCheck //Red color scheme for iCheck
$('input[type="checkbox"].minimal-red, input[type="radio"].minimal-red').iCheck({ $('input[type="checkbox"].minimal-red, input[type="radio"].minimal-red').iCheck({
checkboxClass: 'icheckbox_minimal-red', checkboxClass: 'icheckbox_minimal-red',
radioClass : 'iradio_minimal-red' radioClass: 'iradio_minimal-red'
}) })
//Flat red color scheme for iCheck //Flat red color scheme for iCheck
$('input[type="checkbox"].flat-red, input[type="radio"].flat-red').iCheck({ $('input[type="checkbox"].flat-red, input[type="radio"].flat-red').iCheck({
checkboxClass: 'icheckbox_flat-green', checkboxClass: 'icheckbox_flat-green',
radioClass : 'iradio_flat-green' radioClass: 'iradio_flat-green'
}) })
//Colorpicker //Colorpicker
@ -635,9 +804,10 @@
showInputs: false showInputs: false
}) })
}); });
</script> </script>
<!-- Scripts --> <!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script> <script src="{{ asset('js/app.js') }}" defer></script>
</body> </body>
</html> </html>

View File

@ -2,6 +2,24 @@
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\CityController;
use App\Http\Controllers\Admin\ParkController;
use App\Http\Controllers\Admin\PriceListController;
use App\Http\Controllers\Admin\PriceController;
use App\Http\Controllers\Admin\PsectionController;
use App\Http\Controllers\Admin\PtypeController;
use App\Http\Controllers\Admin\PeriodicalController;
use App\Http\Controllers\Admin\NewsController;
use App\Http\Controllers\Admin\UsersController;
use App\Http\Controllers\Admin\RegularContractController;
use App\Http\Controllers\Admin\ReservesController;
use App\Http\Controllers\Admin\UsertypeController;
use App\Http\Controllers\Admin\ContractorController;
use App\Http\Controllers\Admin\ContractorListController;
use App\Http\Controllers\Admin\UpdateCandidateController;
use App\Http\Controllers\Admin\ReservationController;
/** /**
* Laravel 12変更点:ルート定義の書き方が変更 * Laravel 12変更点:ルート定義の書き方が変更
* Laravel 5.7: Route::get('url', 'Controller@method') の形式 * Laravel 5.7: Route::get('url', 'Controller@method') の形式
@ -93,4 +111,276 @@ Route::middleware('auth')->group(function () {
// Laravel 12対応RESTful API エンドポイント // Laravel 12対応RESTful API エンドポイント
Route::get('/using_status/api', [App\Http\Controllers\Admin\UsingStatusController::class, 'apiGetUtilization'])->name('using_status.api'); Route::get('/using_status/api', [App\Http\Controllers\Admin\UsingStatusController::class, 'apiGetUtilization'])->name('using_status.api');
Route::get('/using_status/export', [App\Http\Controllers\Admin\UsingStatusController::class, 'exportCsv'])->name('using_status.export'); Route::get('/using_status/export', [App\Http\Controllers\Admin\UsingStatusController::class, 'exportCsv'])->name('using_status.export');
// [東京都|〇〇駐輪場] 定期種別マスタ
Route::match(['get', 'post'], '/regular_types', [App\Http\Controllers\Admin\RegularTypeController::class, 'list'])->name('regular_types');
Route::match(['get', 'post'], '/regular_types/add', [App\Http\Controllers\Admin\RegularTypeController::class, 'add'])->name('regular_type_add');
Route::match(['get', 'post'], '/regular_types/edit/{id}', [App\Http\Controllers\Admin\RegularTypeController::class, 'edit'])->where(['id' => '[0-9]+'])->name('regular_type_edit');
Route::match(['get', 'post'], '/regular_types/info/{id}', [App\Http\Controllers\Admin\RegularTypeController::class, 'info'])->where(['id' => '[0-9]+'])->name('regular_type_info');
Route::match(['get', 'post'], '/regular_types/delete', [App\Http\Controllers\Admin\RegularTypeController::class, 'delete'])->name('regular_types_delete');
Route::match(['get', 'post'], '/regular_types/import', [App\Http\Controllers\Admin\RegularTypeController::class, 'import'])->name('regular_types_import');
Route::get('/regular_types/export', [App\Http\Controllers\Admin\RegularTypeController::class, 'export'])->name('regular_types_export');
// [東京都|〇〇駐輪場] 近傍駅マスタ
Route::match(['get', 'post'], '/neighbor_stations', [App\Http\Controllers\Admin\NeighborStationController::class, 'list'])->name('neighbor_stations');
Route::match(['get', 'post'], '/neighbor_stations/add', [App\Http\Controllers\Admin\NeighborStationController::class, 'add'])->name('neighbor_station_add');
Route::match(['get', 'post'], '/neighbor_stations/edit/{id}', [App\Http\Controllers\Admin\NeighborStationController::class, 'edit'])->where(['id' => '[0-9]+'])->name('neighbor_station_edit');
Route::get('/neighbor_stations/info/{id}', [App\Http\Controllers\Admin\NeighborStationController::class, 'info'])->where(['id' => '[0-9]+'])->name('neighbor_station_info');
Route::match(['get', 'post'], '/neighbor_stations/delete', [App\Http\Controllers\Admin\NeighborStationController::class, 'delete'])->name('neighbor_stations_delete');
Route::post('/neighbor_stations/import', [App\Http\Controllers\Admin\NeighborStationController::class, 'import'])->name('neighbor_stations_import');
Route::get('/neighbor_stations/export', [App\Http\Controllers\Admin\NeighborStationController::class, 'export'])->name('neighbor_stations_export');
// [東京都|〇〇駐輪場] 利用契約マスタ
Route::match(['get', 'post'], '/terms', [App\Http\Controllers\Admin\TermsController::class, 'list'])->name('terms'); // 一覧表示
Route::match(['get', 'post'], '/terms/add', [App\Http\Controllers\Admin\TermsController::class, 'add'])->name('terms_add'); // 新規登録画面・登録処理
Route::match(['get', 'post'], '/terms/edit/{term_id}', [App\Http\Controllers\Admin\TermsController::class, 'edit'])->where(['term_id' => '[0-9]+'])->name('terms_edit'); // 編集画面・更新処理
Route::match(['get', 'post'], '/terms/info/{term_id}', [App\Http\Controllers\Admin\TermsController::class, 'info'])->where(['term_id' => '[0-9]+'])->name('terms_info'); // 詳細表示
Route::match(['get', 'post'], '/terms/delete', [App\Http\Controllers\Admin\TermsController::class, 'delete'])->name('terms_delete'); // 削除処理(複数可)
Route::match(['get', 'post'], '/terms/import', [App\Http\Controllers\Admin\TermsController::class, 'import'])->name('terms_import'); // CSVインポート
Route::get('/terms/export', [App\Http\Controllers\Admin\TermsController::class, 'export'])->name('terms_export'); // CSVエクスポート
// [東京都|〇〇駐輪場] 管轄駐輪場マスタ
Route::match(['get', 'post'], '/jurisdiction_parkings', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'list'])->name('jurisdiction_parkings'); // 一覧表示
Route::match(['get', 'post'], '/jurisdiction_parkings/add', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'add'])->name('jurisdiction_parkings_add'); // 新規登録画面・登録処理
Route::match(['get', 'post'], '/jurisdiction_parkings/edit/{jurisdiction_parking_id}', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'edit'])->where(['jurisdiction_parking_id' => '[0-9]+'])->name('jurisdiction_parkings_edit'); // 編集画面・更新処理
Route::match(['get', 'post'], '/jurisdiction_parkings/info/{jurisdiction_parking_id}', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'info'])->where(['jurisdiction_parking_id' => '[0-9]+'])->name('jurisdiction_parkings_info'); // 詳細表示
Route::match(['get', 'post'], '/jurisdiction_parkings/delete', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'delete'])->name('jurisdiction_parkings_delete'); // 削除処理(複数可)
Route::match(['get', 'post'], '/jurisdiction_parkings/import', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'import'])->name('jurisdiction_parkings_import'); // CSVインポート
Route::get('/jurisdiction_parkings/export', [App\Http\Controllers\Admin\JurisdictionParkingController::class, 'export'])->name('jurisdiction_parkings_export'); // CSVエクスポート
// [東京都|〇〇駐輪場] シール印刷範囲マスタ
Route::match(['get', 'post'], '/print_areas', [App\Http\Controllers\Admin\PrintAreaController::class, 'list'])->name('print_areas');
Route::match(['get', 'post'], '/print_areas/add', [App\Http\Controllers\Admin\PrintAreaController::class, 'add'])->name('print_areas_add');
Route::match(['get', 'post'], '/print_areas/edit/{print_area_id}', [App\Http\Controllers\Admin\PrintAreaController::class, 'edit'])->name('print_areas_edit')->where(['print_area_id' => '[0-9]+']);
Route::match(['get', 'post'], '/print_areas/info/{print_area_id}', [App\Http\Controllers\Admin\PrintAreaController::class, 'info'])->name('print_areas_info')->where(['print_area_id' => '[0-9]+']);
Route::match(['get', 'post'], '/print_areas/delete', [App\Http\Controllers\Admin\PrintAreaController::class, 'delete'])->name('print_areas_delete');
Route::match(['get', 'post'], '/print_areas/import', [App\Http\Controllers\Admin\PrintAreaController::class, 'import'])->name('print_areas_import');
Route::get('/print_areas/export', [App\Http\Controllers\Admin\PrintAreaController::class, 'export'])->name('print_areas_export');
// [東京都|〇〇駐輪場] 契約許容市区マスタ
Route::match(['get', 'post'], '/contract_allowable_cities', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'list'])->name('contract_allowable_cities');
Route::match(['get', 'post'], '/contract_allowable_cities/add', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'add'])->name('contract_allowable_cities_add');
Route::match(['get', 'post'], '/contract_allowable_cities/edit/{contract_allowable_city_id}', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'edit'])->name('contract_allowable_cities_edit')->where(['contract_allowable_city_id' => '[0-9]+']);
Route::match(['get', 'post'], '/contract_allowable_cities/info/{contract_allowable_city_id}', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'info'])->name('contract_allowable_cities_info')->where(['contract_allowable_city_id' => '[0-9]+']);
Route::match(['get', 'post'], '/contract_allowable_cities/delete', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'delete'])->name('contract_allowable_cities_delete');
Route::match(['get', 'post'], '/contract_allowable_cities/import', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'import'])->name('contract_allowable_cities_import');
Route::get('/contract_allowable_cities/export', [App\Http\Controllers\Admin\ContractAllowableCityController::class, 'export'])->name('contract_allowable_cities_export');
// [東京都|〇〇駐輪場] 管駐輪場管理者マスタ
Route::match(['get', 'post'], '/managers', [App\Http\Controllers\Admin\ManagerController::class, 'list'])->name('managers');
Route::match(['get', 'post'], '/managers/add', [App\Http\Controllers\Admin\ManagerController::class, 'add'])->name('managers_add');
Route::match(['get', 'post'], '/managers/edit/{manager_id}', [App\Http\Controllers\Admin\ManagerController::class, 'edit'])->name('managers_edit')->where(['manager_id' => '[0-9]+']);
Route::match(['get', 'post'], '/managers/info/{manager_id}', [App\Http\Controllers\Admin\ManagerController::class, 'info'])->name('managers_info')->where(['manager_id' => '[0-9]+']);
Route::match(['get', 'post'], '/managers/delete', [App\Http\Controllers\Admin\ManagerController::class, 'delete'])->name('managers_delete');
Route::match(['get', 'post'], '/managers/import', [App\Http\Controllers\Admin\ManagerController::class, 'import'])->name('managers_import');
Route::get('/managers/export', [App\Http\Controllers\Admin\ManagerController::class, 'export'])->name('managers_export');
// [東京都|〇〇駐輪場] 消費税マスタ
Route::match(['get', 'post'], '/tax', [App\Http\Controllers\Admin\TaxController::class, 'list'])->name('tax');
Route::match(['get', 'post'], '/tax/add', [App\Http\Controllers\Admin\TaxController::class, 'add'])->name('tax_add');
Route::match(['get', 'post'], '/tax/edit/{tax_id}', [App\Http\Controllers\Admin\TaxController::class, 'edit'])
->name('tax_edit')->where(['tax_id' => '[0-9]+']);
Route::match(['get', 'post'], '/tax/info/{tax_id}', [App\Http\Controllers\Admin\TaxController::class, 'info'])
->name('tax_info')->where(['tax_id' => '[0-9]+']);
Route::match(['get', 'post'], '/tax/delete', [App\Http\Controllers\Admin\TaxController::class, 'delete'])->name('tax_delete');
Route::match(['get', 'post'], '/tax/import', [App\Http\Controllers\Admin\TaxController::class, 'import'])->name('tax_import');
Route::get('/tax/export', [App\Http\Controllers\Admin\TaxController::class, 'export'])->name('tax_export');
// [東京都|〇〇駐輪場] 決済情報マスタ
Route::match(['get', 'post'], '/payments', [App\Http\Controllers\Admin\PaymentController::class, 'list'])->name('payments');
Route::match(['get', 'post'], '/payments/add', [App\Http\Controllers\Admin\PaymentController::class, 'add'])->name('payments_add');
Route::match(['get', 'post'], '/payments/edit/{payment_id}', [App\Http\Controllers\Admin\PaymentController::class, 'edit'])
->name('payments_edit')->where(['payment_id' => '[0-9]+']);
Route::match(['get', 'post'], '/payments/info/{payment_id}', [App\Http\Controllers\Admin\PaymentController::class, 'info'])
->name('payments_info')->where(['payment_id' => '[0-9]+']);
Route::match(['get', 'post'], '/payments/delete', [App\Http\Controllers\Admin\PaymentController::class, 'delete'])->name('payments_delete');
Route::match(['get', 'post'], '/payments/import', [App\Http\Controllers\Admin\PaymentController::class, 'import'])->name('payments_import');
Route::get('/payments/export', [App\Http\Controllers\Admin\PaymentController::class, 'export'])->name('payments_export');
// [東京都|〇〇駐輪場] 決済トランザクション
Route::match(['get', 'post'], '/settlement_transactions', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'list'])->name('settlement_transactions');
Route::match(['get', 'post'], '/settlement_transactions/add', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'add'])->name('settlement_transactions_add');
Route::match(['get', 'post'], '/settlement_transactions/edit/{settlement_transaction_id}', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'edit'])
->name('settlement_transactions_edit')->where(['settlement_transaction_id' => '[0-9]+']);
Route::match(['get', 'post'], '/settlement_transactions/info/{settlement_transaction_id}', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'info'])
->name('settlement_transactions_info')->where(['settlement_transaction_id' => '[0-9]+']);
Route::match(['get', 'post'], '/settlement_transactions/delete', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'delete'])->name('settlement_transactions_delete');
Route::match(['get', 'post'], '/settlement_transactions/import', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'import'])->name('settlement_transactions_import');
Route::get('/settlement_transactions/export', [App\Http\Controllers\Admin\SettlementTransactionController::class, 'export'])->name('settlement_transactions_export');
// [東京都|〇〇駐輪場] オペレーターマスタ
Route::match(['get','post'], '/ope', [App\Http\Controllers\Admin\OpeController::class, 'list'])->name('opes');
Route::match(['get','post'], '/ope/add', [App\Http\Controllers\Admin\OpeController::class, 'add'])->name('opes_add');
Route::match(['get','post'], '/ope/edit/{id}', [App\Http\Controllers\Admin\OpeController::class, 'edit'])
->where(['id' => '[0-9]+'])->name('opes_edit');
Route::match(['get','post'], '/ope/info/{id}', [App\Http\Controllers\Admin\OpeController::class, 'info'])
->where(['id' => '[0-9]+'])->name('opes_info');
Route::match(['get','post'], '/ope/delete', [App\Http\Controllers\Admin\OpeController::class, 'delete'])->name('opes_delete');
Route::match(['get','post'], '/ope/import', [App\Http\Controllers\Admin\OpeController::class, 'import'])->name('opes_import');
Route::get('/ope/export', [App\Http\Controllers\Admin\OpeController::class, 'export'])->name('opes_export');
// [東京都|〇〇駐輪場] デバイス管理マスタ
Route::match(['get', 'post'], '/device', [App\Http\Controllers\Admin\DeviceController::class, 'list'])->name('devices');
Route::match(['get', 'post'], '/device/add', [App\Http\Controllers\Admin\DeviceController::class, 'add'])->name('devices_add');
Route::match(['get', 'post'], '/device/edit/{id}', [App\Http\Controllers\Admin\DeviceController::class, 'edit'])
->where(['id' => '[0-9]+'])->name('devices_edit');
Route::match(['get', 'post'], '/device/info/{id}', [App\Http\Controllers\Admin\DeviceController::class, 'info'])
->where(['id' => '[0-9]+'])->name('devices_info');
Route::match(['get', 'post'], '/device/delete', [App\Http\Controllers\Admin\DeviceController::class, 'delete'])->name('devices_delete');
Route::match(['get', 'post'], '/device/import', [App\Http\Controllers\Admin\DeviceController::class, 'import'])->name('devices_import');
Route::get('/device/export', [App\Http\Controllers\Admin\DeviceController::class, 'export'])->name('devices_export');
// [東京都|〇〇駐輪場] オペレーターキュー
Route::match(['get', 'post'], '/operator_que', [App\Http\Controllers\Admin\OperatorQueController::class, 'list'])->middleware('auth')->name('operator_ques');
Route::match(['get', 'post'], '/operator_que/add', [App\Http\Controllers\Admin\OperatorQueController::class, 'add'])->middleware('auth')->name('operator_ques_add');
Route::match(['get', 'post'], '/operator_que/edit/{id}', [App\Http\Controllers\Admin\OperatorQueController::class, 'edit'])->where(['id' => '[0-9]+'])->middleware('auth')->name('operator_ques_edit');
Route::match(['get', 'post'], '/operator_que/info/{id}', [App\Http\Controllers\Admin\OperatorQueController::class, 'info'])->where(['id' => '[0-9]+'])->middleware('auth')->name('operator_ques_info');
Route::match(['get', 'post'], '/operator_que/delete', [App\Http\Controllers\Admin\OperatorQueController::class, 'delete'])->name('operator_ques_delete');
Route::match(['get', 'post'], '/operator_ques/import', [App\Http\Controllers\Admin\OperatorQueController::class, 'import'])->name('operator_ques_import');
Route::get('/operator_ques/export', [App\Http\Controllers\Admin\OperatorQueController::class, 'export'])->name('operator_ques_export');
// [東京都|〇〇駐輪場] 設定マスタ
Route::match(['get', 'post'], '/setting', [App\Http\Controllers\Admin\SettingController::class, 'list'])
->middleware('auth')->name('settings');
Route::match(['get', 'post'], '/setting/add', [App\Http\Controllers\Admin\SettingController::class, 'add'])
->middleware('auth')->name('settings_add');
Route::match(['get', 'post'], '/setting/edit/{id}', [App\Http\Controllers\Admin\SettingController::class, 'edit'])
->where(['id' => '[0-9]+'])->middleware('auth')->name('settings_edit');
Route::match(['get', 'post'], '/setting/info/{id}', [App\Http\Controllers\Admin\SettingController::class, 'info'])
->where(['id' => '[0-9]+'])->middleware('auth')->name('settings_info');
Route::match(['get', 'post'], '/setting/delete', [App\Http\Controllers\Admin\SettingController::class, 'delete'])
->middleware('auth')->name('settings_delete');
// sou start
// [東京都|〇〇駐輪場] 定期契約マスタ
Route::match(['get', 'post'], '/regular_contracts', [App\Http\Controllers\Admin\RegularContractController::class, 'list'])->name('regular_contracts');
Route::match(['get', 'post'], '/regular_contracts/add', [App\Http\Controllers\Admin\RegularContractController::class, 'add'])->name('regular_contract_add');
Route::match(['get', 'post'], '/regular_contracts/edit/{contract_id}', [App\Http\Controllers\Admin\RegularContractController::class, 'edit'])->name('regular_contract_edit')->where(['contract_id' => '[0-9]+']);
Route::match(['get', 'post'], '/regular_contracts/info/{contract_id}', [App\Http\Controllers\Admin\RegularContractController::class, 'info'])->name('regular_contract_info')->where(['contract_id' => '[0-9]+']);
Route::match(['get', 'post'], '/regular_contracts/delete', [App\Http\Controllers\Admin\RegularContractController::class, 'delete'])->name('regular_contracts_delete');
Route::match(['get', 'post'], '/regular_contracts/import', [App\Http\Controllers\Admin\RegularContractController::class, 'import'])->name('regular_contracts_import');
Route::get('/regular_contracts/export', [App\Http\Controllers\Admin\RegularContractController::class, 'export'])->name('regular_contracts_export');
// [東京都|〇〇駐輪場] 駐輪車室マスタ
Route::match(['get', 'post'], '/pplace', [PplaceController::class, 'list'])->name('pplace');
Route::match(['get', 'post'], '/pplace/add', [PplaceController::class, 'add'])->name('pplace_add');
Route::match(['get', 'post'], '/pplace/edit/{id}', [PplaceController::class, 'edit'])->name('pplace_edit')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/pplace/info/{id}', [PplaceController::class, 'info'])->name('pplace_info')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/pplace/delete', [PplaceController::class, 'delete'])->name('pplace_delete');
Route::match(['get', 'post'], '/pplace/import', [PplaceController::class, 'import'])->name('pplace_import');
Route::get('/pplace/export', [PplaceController::class, 'export'])->name('pplace_export');
// sou end
// ou start
// 市区マスタ
Route::match(['get', 'post'], '/city', [CityController::class, 'list'])->name('city');
Route::match(['get', 'post'], '/city/add', [CityController::class, 'add'])->name('city_add');
Route::match(['get', 'post'], '/city/edit/{id}', [CityController::class, 'edit'])->where(['id' => '[0-9]+'])->name('city_edit');
Route::match(['get', 'post'], '/city/info/{id}', [CityController::class, 'info'])->where(['id' => '[0-9]+'])->name('city_info');
Route::match(['get', 'post'], '/city/delete', [CityController::class, 'delete'])->name('city_delete');
// 駐輪場マスタ
Route::get('/parks', [ParkController::class, 'list'])->name('parks');
Route::get('/parks/add', [ParkController::class, 'add'])->name('parks.add');
Route::post('/parks/add', [ParkController::class, 'add'])->name('parks.store');
Route::match(['get', 'post', 'put'], '/parks/edit/{id}', [ParkController::class, 'edit'])->name('parks.edit');
Route::put('/parks/edit/{id}', [ParkController::class, 'edit'])->name('parks.update');
Route::match(['get', 'post'], '/parks/delete', [ParkController::class, 'delete'])->name('parks.delete');
Route::get('/parks/export', [ParkController::class, 'export'])->name('parks.export');
Route::post('/parks/check-duplicate', [App\Http\Controllers\Admin\ParkController::class, 'checkDuplicate'])->name('parks.check_duplicate');
// 料金一覧表マスタ
Route::match(['get', 'post'], '/admin/pricelist', [PriceListController::class, 'list'])->name('pricelist');
Route::post('/admin/pricelist/update', [PriceListController::class, 'update'])->name('pricelist_update');
Route::post('/admin/pricelist/insert', [PriceListController::class, 'insert'])->name('pricelist_insert');
//駐輪場所、料金マスタ
Route::match(['get', 'post'], '/admin/prices', [PriceController::class, 'list'])->name('prices');
Route::match(['get', 'post'], '/admin/prices/add', [PriceController::class, 'add'])->name('price_add');
Route::match(['get', 'post'], '/admin/prices/edit/{id}', [PriceController::class, 'edit'])->name('price_edit')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/admin/prices/info/{id}', [PriceController::class, 'info'])->name('price_info')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/admin/prices/delete', [PriceController::class, 'delete'])->name('prices_delete');
Route::match(['get', 'post'], '/admin/prices/import', [PriceController::class, 'import'])->name('prices_import');
Route::get('/admin/prices/export', [PriceController::class, 'export'])->name('prices_export');
//車種区分マスタ
Route::match(['get', 'post'], '/admin/psection', [PsectionController::class, 'list'])->name('psection');
Route::match(['get', 'post'], '/admin/psection/add', [PsectionController::class, 'add'])->name('psection_add');
Route::match(['get', 'post'], '/admin/psection/edit/{id}', [PsectionController::class, 'edit'])->name('psection_edit')->where(['id' => '[0-9]+']);
Route::post('/admin/psection/delete', [PsectionController::class, 'delete'])->name('psection_delete');
//駐輪分類マスタ
Route::match(['get', 'post'], '/admin/ptypes', [PtypeController::class, 'list'])->name(name: 'ptypes');
Route::match(['get', 'post'], '/admin/ptypes/add', [PtypeController::class, 'add'])->name('ptype_add');
Route::match(['get', 'post'], '/admin/ptypes/edit/{id}', [PtypeController::class, 'edit'])->name('ptype_edit')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/admin/ptypes/info/{id}', [PtypeController::class, 'info'])->name('ptype_info')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/admin/ptypes/delete', [PtypeController::class, 'delete'])->name('ptype_delete');
Route::match(['get', 'post'], '/admin/ptypes/import', [PtypeController::class, 'import'])->name('ptype_import');
Route::get('/admin/ptypes/export', [PtypeController::class, 'export'])->name('ptype_export');
//定期利用・契約状況
Route::match(['get', 'post'], '/periodical', [PeriodicalController::class, 'list'])->name('periodical');
Route::get('/periodical/list-data', [PeriodicalController::class, 'listData'])->name('periodical.listData');
Route::get('/periodical/area', [PeriodicalController::class, 'area'])->name('periodical.area');
Route::get('/periodical/area-list-data', [PeriodicalController::class, 'areaListData'])->name('periodical.areaListData');
// 一般ウェブ管理 最新ニュース登録
Route::match(['get', 'post'], '/web/news', [NewsController::class, 'list'])->name('news');
Route::match(['get', 'post'], '/web/news/add', [NewsController::class, 'add'])->name('news_add');
Route::match(['get', 'post'], '/web/news/edit/{id}', [NewsController::class, 'edit'])->where(['id' => '[0-9]+'])->name('news_edit');
Route::match(['get', 'post'], '/web/news/info/{id}', [NewsController::class, 'info'])->where(['id' => '[0-9]+'])->name('news_info');
Route::match(['get', 'post'], '/web/news/delete', [NewsController::class, 'delete'])->name('news_delete');
// 利用者マスタ
Route::match(['get', 'post'], '/users', [UsersController::class, 'list'])->name('users');
Route::match(['get', 'post'], '/users/add', [UsersController::class, 'add'])->name('users_add');
Route::match(['get', 'post'], '/users/export', [UsersController::class, 'export'])->name('users_export');
// 定期契約マスタ
Route::match(['get', 'post'], '/regularcontracts', [RegularContractController::class, 'list'])->name('regularcontracts');
Route::match(['get', 'post'], '/regularcontracts/add', [RegularContractController::class, 'add'])->name('regularcontracts_add');
Route::match(['get', 'post'], '/regularcontracts/edit/{contract_id}', [RegularContractController::class, 'edit'])->where(['contract_id' => '[0-9]+'])->name('regularcontracts_edit');
Route::match(['get', 'post'], '/regularcontracts/import', [RegularContractController::class, 'import'])->name('regularcontracts_import');
Route::get('/regularcontracts/export', [RegularContractController::class, 'export'])->name('regularcontracts_export')->middleware('auth');
Route::match(['get', 'post'], '/regularcontracts/info/{contract_id}', [RegularContractController::class, 'info'])->where(['contract_id' => '[0-9]+'])->name('regularcontracts_info');
Route::match(['get', 'post'], '/regularcontracts/delete', [RegularContractController::class, 'delete'])->name('regularcontracts_delete');
// 定期予約マスタ
Route::match(['get', 'post'], '/reserves', [ReservesController::class, 'list'])->name('reserves');
Route::match(['get', 'post'], '/reserves/add', [ReservesController::class, 'add'])->name('reserves_add');
Route::match(['get', 'post'], '/reserves/edit/{reserve_id}', [ReservesController::class, 'edit'])->name('reserves_edit');
Route::match(['get', 'post'], '/reserves/delete', [ReservesController::class, 'delete'])->name('reserves_delete');
Route::match(['get', 'post'], '/reserves/export', [ReservesController::class, 'export'])->name('reserves_export');
// 利用者分類マスタ
Route::match(['get', 'post'], '/usertypes', [UsertypeController::class, 'list'])->name('usertypes');
Route::match(['get', 'post'], '/usertypes/add', [UsertypeController::class, 'add'])->name('usertype_add');
Route::match(['get', 'post'], '/usertypes/edit/{id}', [UsertypeController::class, 'edit'])->name('usertype_edit')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/usertypes/info/{id}', [UsertypeController::class, 'info'])->name('usertype_info')->where(['id' => '[0-9]+']);
Route::match(['get', 'post'], '/usertypes/delete', [UsertypeController::class, 'delete'])->name('usertypes_delete');
Route::match(['get', 'post'], '/usertypes/import', [UsertypeController::class, 'import'])->name('usertypes_import');
Route::get('/usertypes/export', [UsertypeController::class, 'export'])->name('usertypes_export');
// 契約者一覧
Route::match(['get', 'post'], '/contractor', [ContractorController::class, 'list'])->name('contractor');
// 未更新者一覧
Route::match(['get', 'post'], '/contractor_list', [ContractorListController::class, 'list'])->name('contractor_List');
// 更新予定者一覧
Route::match(['get', 'post'], '/update_candidate', [UpdateCandidateController::class, 'list'])->name('update_candidate');
// 予約者一覧
Route::match(['get', 'post'], '/reservation', [ReservationController::class, 'list'])->name('reservation');
}); });