【定期予約マスタ】絞り込みボダン修正
All checks were successful
Deploy main / deploy (push) Successful in 24s

This commit is contained in:
你的名字 2025-10-07 10:16:17 +09:00
parent dd88338fb1
commit 97e85533c6
4 changed files with 729 additions and 381 deletions

View File

@ -6,6 +6,10 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use App\Models\Park;
use App\Models\PriceA;
use App\Models\PriceB;
use Illuminate\Support\Facades\Auth;
class ReservesController class ReservesController
{ {
@ -24,7 +28,7 @@ class ReservesController
{ {
// ── 並び順(既定: reserve_id DESC────────────────────────────── // ── 並び順(既定: reserve_id DESC──────────────────────────────
$sort = $request->input('sort', 'reserve_id'); $sort = $request->input('sort', 'reserve_id');
$sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc'; $sortType = strtolower($request->input('sort_type', 'asc')) === 'desc' ? 'desc' : 'asc';
// ── 絞り込み(必要最低限:利用者/駐輪場/期間)────────────────── // ── 絞り込み(必要最低限:利用者/駐輪場/期間)──────────────────
$userId = trim((string) $request->input('user_id', '')); $userId = trim((string) $request->input('user_id', ''));
@ -32,14 +36,32 @@ class ReservesController
$fromDt = $request->input('reserve_date_from', ''); $fromDt = $request->input('reserve_date_from', '');
$toDt = $request->input('reserve_date_to', ''); $toDt = $request->input('reserve_date_to', '');
$keyword = trim((string) $request->input('keyword', '')); // 利用者名かな など $keyword = trim((string) $request->input('keyword', '')); // 利用者名かな など
$validFlag = trim((string) $request->input('valid_flag', ''));
$mailSentFrom = $request->input('mail_sent_from', '');
$mailSentTo = $request->input('mail_sent_to', '');
$priceUnion = DB::query()->fromSub(function ($sub) {
$sub->from('price_a')
->select('price_parkplaceid', 'prine_name')
->unionAll(
DB::table('price_b')->select('price_parkplaceid', 'prine_name')
);
}, 'price_union');
// ── クエリ構築 ──────────────────────────────────────────────── // ── クエリ構築 ────────────────────────────────────────────────
$q = DB::table('reserve as r') $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('user as u', 'u.user_id', '=', 'r.user_id')
->leftJoin('park as p', 'p.park_id', '=', 'r.park_id') // park: park_name 等【turn12file4†L17-L25】 ->leftJoin('park as p', 'p.park_id', '=', 'r.park_id')
->leftJoin('psection as ps', 'ps.psection_id', '=', 'r.psection_id')
->leftJoin('ptype as pt', 'pt.ptype_id', '=', 'r.ptype_id')
->leftJoin('usertype as t', 't.user_categoryid', '=', 'r.user_categoryid')
->leftJoinSub($priceUnion, 'price_union', function ($join) {
$join->on('price_union.price_parkplaceid', '=', 'r.price_parkplaceid');
})
->select([ ->select([
'r.reserve_id', 'r.reserve_id',
'r.contract_id', 'r.contract_id',
'r.contract_created_at',
'r.user_id', 'r.user_id',
'r.park_id', 'r.park_id',
'r.price_parkplaceid', 'r.price_parkplaceid',
@ -47,19 +69,36 @@ class ReservesController
'r.reserve_date', 'r.reserve_date',
'r.reserve_start', 'r.reserve_start',
'r.reserve_end', 'r.reserve_end',
'r.reserve_reduction',
'r.reserve_auto_remind',
'r.reserve_manual_remind',
DB::raw('r.`800m_flag` as flag_800m'),
'r.reserve_cancelday', 'r.reserve_cancelday',
'r.valid_flag', 'r.valid_flag',
'r.reserve_manual',
'r.reserve_notice',
'r.sent_date',
'r.reserve_order',
'r.valid_flag',
'r.ope_id', 'r.ope_id',
'r.user_categoryid',
DB::raw('u.user_name as user_name'), DB::raw('u.user_name as user_name'),
DB::raw('u.user_phonetic as user_phonetic'), DB::raw('u.user_phonetic as user_phonetic'),
DB::raw('u.user_mobile as user_mobile'), DB::raw('u.user_mobile as user_mobile'),
DB::raw('p.park_name as park_name'), DB::raw('p.park_name as park_name'),
DB::raw('pt.ptype_subject as ptype_subject'),
DB::raw('ps.psection_subject as psection_subject'),
DB::raw('price_union.price_parkplaceid as display_price_parkplaceid'),
DB::raw('price_union.prine_name as display_prine_name'),
DB::raw('t.usertype_subject1 as usertype_subject1'),
DB::raw('t.usertype_subject2 as usertype_subject2'),
DB::raw('t.usertype_subject3 as usertype_subject3'),
]); ]);
if ($userId !== '') if ($userId !== '')
$q->where('r.user_id', 'like', "%{$userId}%"); $q->where('r.user_id', 'like', "%{$userId}%");
if ($parkId !== '') if ($parkId !== '')
$q->where('r.park_id', 'like', "%{$parkId}%"); $q->where('r.park_id', '=', (int) $parkId);
if ($fromDt) if ($fromDt)
$q->whereDate('r.reserve_date', '>=', $fromDt); $q->whereDate('r.reserve_date', '>=', $fromDt);
@ -72,36 +111,108 @@ class ReservesController
->orWhere('u.user_phonetic', 'like', "%{$keyword}%"); ->orWhere('u.user_phonetic', 'like', "%{$keyword}%");
}); });
} }
if (in_array($validFlag, ['0', '1'], true)) {
$q->where('r.valid_flag', '=', (int) $validFlag);
}
if ($mailSentFrom !== null && $mailSentFrom !== '') {
$q->where('r.sent_date', '>=', $mailSentFrom);
}
if ($mailSentTo !== null && $mailSentTo !== '') {
$q->where('r.sent_date', '<=', $mailSentTo);
}
// ソート許可カラムJOIN 先も含む) // ソート許可カラムJOIN 先も含む)
$sortable = [ $sortable = [
'reserve_id', 'reserve_id',
'contract_id', 'contract_id',
'contract_created_at',
'user_categoryid',
'user_id', 'user_id',
'park_id',
'reserve_date', 'reserve_date',
'reserve_start', 'park_price_name',
'reserve_end', 'price_parkplaceid',
'psection_subject',
'ptype_subject',
'park_name',
'reserve_reduction',
'reserve_auto_remind',
'reserve_manual_remind',
'flag_800m',
'reserve_cancelday', 'reserve_cancelday',
'valid_flag', 'valid_flag',
'ope_id', 'sent_date',
'user_name', 'reserve_manual',
'user_phonetic', 'reserve_notice',
'user_mobile', 'reserve_order',
'park_name',
]; ];
if (!in_array($sort, $sortable, true)) if (!in_array($sort, $sortable, true)) {
$sort = 'reserve_id'; $sort = 'reserve_id';
}
$sortMap = [ $sortMap = [
'user_name' => 'u.user_name', 'reserve_id' => DB::raw('r.reserve_id'),
'user_phonetic' => 'u.user_phonetic', 'contract_id' => DB::raw('r.contract_id'),
'user_mobile' => 'u.user_mobile', 'contract_created_at' => DB::raw('r.contract_created_at'),
'park_name' => 'p.park_name', 'user_categoryid' => DB::raw('r.user_categoryid'),
'user_id' => DB::raw('r.user_id'),
'reserve_date' => DB::raw('r.reserve_date'),
'park_price_name' => DB::raw('price_union.prine_name'),
'price_parkplaceid' => DB::raw('r.price_parkplaceid'),
'psection_subject' => DB::raw('ps.psection_subject'),
'ptype_subject' => DB::raw('pt.ptype_subject'),
'park_name' => DB::raw('p.park_name'),
'reserve_reduction' => DB::raw('r.reserve_reduction'),
'reserve_auto_remind' => DB::raw('r.reserve_auto_remind'),
'reserve_manual_remind' => DB::raw('r.reserve_manual_remind'),
'flag_800m' => DB::raw('r.`800m_flag`'),
'reserve_cancelday' => DB::raw('r.reserve_cancelday'),
'valid_flag' => DB::raw('r.valid_flag'),
'sent_date' => DB::raw('r.sent_date'),
'reserve_manual' => DB::raw('r.reserve_manual'),
'reserve_notice' => DB::raw('r.reserve_notice'),
'reserve_order' => DB::raw('r.reserve_order'),
]; ];
$sortCol = $sortMap[$sort] ?? ('r.' . $sort); $sortColumn = $sortMap[$sort] ?? DB::raw('r.reserve_id');
$q->orderBy($sortColumn, $sortType);
$list = $q->orderBy($sortCol, $sortType)->paginate(50); $parkOptions = Park::query()
->orderBy('park_id', 'asc')
->pluck('park_name', 'park_id')
->toArray();
$list = $q->paginate(50);
$placeIds = $list->getCollection()
->pluck('price_parkplaceid')
->filter()
->unique()
->values()
->all();
if (!empty($placeIds)) {
$priceNamesA = PriceA::query()
->whereIn('price_parkplaceid', $placeIds)
->pluck('prine_name', 'price_parkplaceid')
->toArray();
$priceNamesB = PriceB::query()
->whereIn('price_parkplaceid', $placeIds)
->pluck('prine_name', 'price_parkplaceid')
->toArray();
// 駐輪場所名のマッピングprice_b で上書き)
$priceNames = array_replace($priceNamesA, $priceNamesB);
$list->setCollection(
$list->getCollection()->map(function ($row) use ($priceNames) {
$id = $row->price_parkplaceid ?? null;
$row->display_prine_name = ($id !== null && array_key_exists($id, $priceNames))
? $priceNames[$id]
: null;
return $row;
})
);
}
return view('admin.reserves.list', [ return view('admin.reserves.list', [
'list' => $list, 'list' => $list,
@ -113,6 +224,10 @@ class ReservesController
'reserve_date_from' => $fromDt, 'reserve_date_from' => $fromDt,
'reserve_date_to' => $toDt, 'reserve_date_to' => $toDt,
'keyword' => $keyword, 'keyword' => $keyword,
'valid_flag' => $validFlag,
'mail_sent_from' => $mailSentFrom,
'mail_sent_to' => $mailSentTo,
'parkOptions' => $parkOptions,
]); ]);
} }
@ -122,7 +237,44 @@ class ReservesController
public function add(Request $request) public function add(Request $request)
{ {
if ($request->isMethod('get')) { if ($request->isMethod('get')) {
return view('admin.reserves.add'); $userTypes = DB::table('usertype')
->orderBy('user_categoryid', 'asc')
->get([
'user_categoryid',
'usertype_subject1',
'usertype_subject2',
'usertype_subject3',
])
->map(function ($row) {
$labels = array_filter([
$row->usertype_subject1,
$row->usertype_subject2,
$row->usertype_subject3,
], fn ($v) => $v !== null && $v !== '');
$row->display_name = $labels ? implode('/', $labels) : '';
return $row;
});
$parks = Park::query()
->orderBy('park_id', 'asc')
->get(['park_id', 'park_name']);
$priceA = PriceA::query()
->select('price_parkplaceid', 'prine_name')
->get();
$priceB = PriceB::query()
->select('price_parkplaceid', 'prine_name')
->get();
$priceOptions = $priceA->merge($priceB)
->sortBy('price_parkplaceid', SORT_NATURAL)
->unique('price_parkplaceid')
->values();
return view('admin.reserves.add', [
'userTypes' => $userTypes,
'parks' => $parks,
'priceOptions' => $priceOptions,
]);
} }
// 予約の最低限バリデーション(必要に応じて追加) // 予約の最低限バリデーション(必要に応じて追加)
@ -141,19 +293,28 @@ class ReservesController
return back()->withErrors($v)->withInput(); return back()->withErrors($v)->withInput();
} }
$now = now();
$opeId = optional(Auth::user())->ope_id;
$nextReserveId = DB::transaction(function () {
$currentMax = DB::table('reserve')->max('reserve_id');
return $currentMax ? $currentMax + 1 : 1;
});
DB::table('reserve')->insert([ DB::table('reserve')->insert([
'reserve_id' => $nextReserveId,
'user_id' => (int) $request->input('user_id'), 'user_id' => (int) $request->input('user_id'),
'park_id' => (int) $request->input('park_id'), 'park_id' => (int) $request->input('park_id'),
'contract_id' => $request->input('contract_id'), // 任意regular_contract と紐づける場合【turn12file7†L20-L28】 'contract_id' => $request->input('contract_id'),
'price_parkplaceid' => $request->input('price_parkplaceid'), 'price_parkplaceid' => $request->input('price_parkplaceid'),
'psection_id' => $request->input('psection_id'), 'psection_id' => $request->input('psection_id'),
'reserve_date' => $request->input('reserve_date'), 'reserve_date' => $request->input('reserve_date'),
'reserve_start' => $request->input('reserve_start'), 'reserve_start' => $now,
'reserve_end' => $request->input('reserve_end'), 'reserve_end' => $now,
'valid_flag' => $request->input('valid_flag'), 'valid_flag' => $request->input('valid_flag'),
'ope_id' => $request->input('ope_id'), 'ope_id' => $opeId,
'created_at' => now(), 'created_at' => $now,
'updated_at' => now(), 'updated_at' => $now,
]); ]);
return redirect()->route('reserves')->with('success', '予約を登録しました。'); return redirect()->route('reserves')->with('success', '予約を登録しました。');
@ -264,8 +425,7 @@ class ReservesController
$parkOptions = DB::table('park') $parkOptions = DB::table('park')
->orderBy('park_id', 'asc') ->orderBy('park_id', 'asc')
->limit(5000) ->pluck('park_name', 'park_id')
->pluck(DB::raw("concat(park_id, ' ', park_name)"), 'park_id')
->toArray(); ->toArray();
$userTypeOptions = Schema::hasTable('usertype') $userTypeOptions = Schema::hasTable('usertype')

View File

@ -48,8 +48,9 @@
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="card"> <div class="card">
<div class="card-header py-2"> <div class="card-header d-flex justify-content-start gap-2">
<button form="rvAddForm" type="submit" class="btn btn-success btn-sm">登録</button> <button type="submit" class="btn btn-sm btn-default register js-confirm-submit">登録</button>
<a href="{{ route('reserves') }}" class="btn btn-sm btn-default ml-2">戻る</a>
</div> </div>
<form id="rvAddForm" method="post" action="{{ route('reserves_add') }}"> <form id="rvAddForm" method="post" action="{{ route('reserves_add') }}">
@ -57,26 +58,25 @@
<div class="card-body"> <div class="card-body">
{{-- 画面上部ID系 --}} {{-- 画面上部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"> <div class="field">
<label class="label">定期契約ID</label> <label class="label">定期契約ID</label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="contract_id" value="{{ old('contract_id') }}"> <input type="number" class="form-control" name="contract_id" value="{{ old('contract_id') }}" placeholder="定期契約ID">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">利用者分類ID</label> <label class="label">利用者分類ID</label>
<div class="input"> <div class="input">
{{-- 任意:必要に応じて選択肢を与える(今は簡易にテキスト or 「全て」) --}}
<select name="user_categoryid" class="form-control"> <select name="user_categoryid" class="form-control">
<option value="">全て</option> <option value="">全て</option>
@foreach($userTypes as $type)
<option value="{{ $type->user_categoryid }}"
{{ old('user_categoryid') == $type->user_categoryid ? 'selected' : '' }}>
{{ $type->display_name }}
</option>
@endforeach
</select> </select>
</div> </div>
</div> </div>
@ -92,42 +92,56 @@
<div class="field"> <div class="field">
<label class="label">利用者ID <span class="text-danger">*</span></label> <label class="label">利用者ID <span class="text-danger">*</span></label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="user_id" value="{{ old('user_id') }}" required> <input type="number" class="form-control" name="user_id" value="{{ old('user_id') }}" required placeholder="利用者ID">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">駐輪場ID <span class="text-danger">*</span></label> <label class="label">駐輪場ID <span class="text-danger">*</span></label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="park_id" value="{{ old('park_id') }}" required> <select name="park_id" class="form-control" required>
<option value="">駐輪場ID</option>
@foreach($parks as $park)
<option value="{{ $park->park_id }}" {{ old('park_id') == $park->park_id ? 'selected' : '' }}>
{{ $park->park_name }}
</option>
@endforeach
</select>
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">駐輪場所ID</label> <label class="label">駐輪場所ID</label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="price_parkplaceid" value="{{ old('price_parkplaceid') }}"> <select name="price_parkplaceid" class="form-control">
<option value="">駐輪場所ID</option>
@foreach($priceOptions as $price)
<option value="{{ $price->price_parkplaceid }}" {{ old('price_parkplaceid') == $price->price_parkplaceid ? 'selected' : '' }}>
{{ $price->price_parkplaceid }} {{ $price->prine_name }}
</option>
@endforeach
</select>
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">車種区分ID</label> <label class="label">車種区分ID</label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="psection_id" value="{{ old('psection_id') }}"> <input type="number" class="form-control" name="psection_id" value="{{ old('psection_id') }}" placeholder="車種区分ID">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">駐輪分類ID</label> <label class="label">駐輪分類ID</label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="ptype_id" value="{{ old('ptype_id') }}"> <input type="number" class="form-control" name="ptype_id" value="{{ old('ptype_id') }}" placeholder="駐輪分類ID">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">予約日時</label> <label class="label">予約日時</label>
<div class="input"> <div class="input">
<input type="datetime-local" class="form-control" name="reserve_date" value="{{ old('reserve_date') }}"> <input type="datetime-local" class="form-control" name="reserve_date" value="{{ old('reserve_date') }}" placeholder="yyyy/mm/dd hh:mm:ss">
</div> </div>
</div> </div>
@ -150,14 +164,14 @@
<div class="field"> <div class="field">
<label class="label">自動リマインド日</label> <label class="label">自動リマインド日</label>
<div class="input"> <div class="input">
<input type="date" class="form-control" name="auto_remind_day" value="{{ old('auto_remind_day') }}"> <input type="date" class="form-control" name="auto_remind_day" value="{{ old('auto_remind_day') }}" placeholder="yyyy/mm/dd">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">手動リマインド日</label> <label class="label">手動リマインド日</label>
<div class="input"> <div class="input">
<input type="date" class="form-control" name="manual_remind_day" value="{{ old('manual_remind_day') }}"> <input type="date" class="form-control" name="manual_remind_day" value="{{ old('manual_remind_day') }}" placeholder="yyyy/mm/dd">
</div> </div>
</div> </div>
@ -179,7 +193,7 @@
<div class="field"> <div class="field">
<label class="label">解約日</label> <label class="label">解約日</label>
<div class="input"> <div class="input">
<input type="date" class="form-control" name="reserve_cancelday" value="{{ old('reserve_cancelday') }}"> <input type="date" class="form-control" name="reserve_cancelday" value="{{ old('reserve_cancelday') }}" placeholder="yyyy/mm/dd">
</div> </div>
</div> </div>
@ -229,49 +243,58 @@
<div class="field"> <div class="field">
<label class="label">空き待ちメール送信日時</label> <label class="label">空き待ちメール送信日時</label>
<div class="input"> <div class="input">
<input type="datetime-local" class="form-control" name="waiting_mail_sent_at" value="{{ old('waiting_mail_sent_at') }}"> <input type="datetime-local" class="form-control" name="waiting_mail_sent_at" value="{{ old('waiting_mail_sent_at') }}" placeholder="yyyy/mm/dd hh:mm:ss">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">空き待ち順</label> <label class="label">空き待ち順</label>
<div class="input"> <div class="input">
<input type="number" class="form-control" name="waiting_order" value="{{ old('waiting_order') }}"> <input type="number" class="form-control" name="waiting_order" value="{{ old('waiting_order') }}" placeholder="空き待ち順">
<div class="help">小さいほど優先度が高い想定</div>
</div> </div>
</div> </div>
{{-- 任意:開始/終了(必要なら表示) --}} <div class="mt-4 d-flex gap-2">
<div class="field"> <button type="submit" class="btn btn-sm btn-default register js-confirm-submit">登録</button>
<label class="label">開始日</label> <a href="{{ route('reserves') }}" class="btn btn-sm btn-default ml-2">戻る</a>
<div class="input">
<input type="date" class="form-control" name="reserve_start" value="{{ old('reserve_start') }}">
</div>
</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> </div>
</form> </form>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
@push('scripts')
<script>
(function ($) {
'use strict';
$(function () {
$(document).off('click.rvConfirm', '.js-confirm-submit').on('click.rvConfirm', '.js-confirm-submit', function (e) {
e.preventDefault();
const $button = $(this);
$.confirm({
title: '確認ダイアログ',
content: '!登録してよろしいですか? はい/いいえ',
buttons: {
yes: {
text: 'はい',
btnClass: 'btn-primary',
action: function () {
let $form = $button.closest('form');
if (!$form.length) {
const formId = $button.attr('form');
$form = formId ? $('#' + formId) : $('form').first();
}
$form.trigger('submit');
}
},
no: { text: 'いいえ' }
}
});
});
});
})(jQuery);
</script>
@endpush
@endsection @endsection

View File

@ -4,22 +4,90 @@
@section('content') @section('content')
<style> <style>
.rv-edit, .rv-edit .card, .rv-edit .form-control, .rv-edit .btn, .rv-edit .breadcrumb{ .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-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; font-size:13px;
line-height:1.45;
}
.rv-form .field{
display:flex;
align-items:center;
gap:1.25rem;
margin-bottom:.75rem;
}
.rv-form .label{
flex:0 0 180px;
margin:0;
color:#333;
font-weight:600;
white-space:nowrap;
}
.rv-form .label .req{
color:#e3342f;
margin-left:.35rem;
}
.rv-form .input{
flex:1 1 auto;
min-width:260px;
}
.rv-form .form-control{
height:calc(2.0rem + 2px);
padding:.25rem .5rem;
}
.rv-form .form-control[readonly],
.rv-form .form-control:disabled{
background:#f5f5f5;
color:#444;
}
.rv-form .radio-inline{
display:inline-flex;
align-items:center;
gap:.35rem;
margin-right:1.25rem;
}
.breadcrumb-inline{
white-space:nowrap;
color:#666;
}
.rv-edit .card-header{
display:flex;
justify-content:flex-start;
gap:.5rem;
padding:1rem 1.25rem;
border-bottom:1px solid #f1f1f1;
}
.rv-edit .card-footer{
background:#fff;
border-top:1px solid #f1f1f1;
display:flex;
justify-content:flex-start;
gap:.5rem;
padding:1rem 1.25rem;
}
@media (max-width: 576px){
.rv-form .field{
flex-direction:column;
align-items:flex-start;
}
.rv-form .label{
flex:none;
}
.rv-toolbar{
flex-direction:column;
align-items:stretch;
}
.rv-toolbar .btn{
width:100%;
}
} }
.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> </style>
@php @php
// 只读显示用:从现有 options 推断名称(不改控制器也能显示) // 読み取り専用表示用:既存のオプションから名称を推定(コントローラを変更せず表示可能)
$userName = ''; $userName = '';
if (!empty($row->user_id ?? null) && !empty($userOptions[$row->user_id] ?? null)) { if (!empty($row->user_id ?? null) && !empty($userOptions[$row->user_id] ?? null)) {
// $userOptions 形如 "12345 山田太郎" → 去掉开头ID只留名字 // $userOptions 形如 "12345 山田太郎" → 去掉开头ID只留名字
@ -37,14 +105,15 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-2"> <div class="d-flex justify-content-between align-items-center mb-2">
<h1 class="m-0 text-dark">編集</h1> <h1 class="m-0 text-dark">編集</h1>
<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> </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')) @if(session('success'))
<div class="alert alert-success py-2 px-3 my-2">{{ session('success') }}</div> <div class="alert alert-success py-2 px-3 my-2">{{ session('success') }}</div>
@endif @endif
@ -60,263 +129,242 @@
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="card rv-form"> <div class="card rv-form">
<div class="card-header">
<button type="submit" class="btn btn-default btn-sm js-confirm-submit" form="edit-form">登録</button>
<button type="button" id="btnDeleteTop" class="btn btn-default btn-sm">削除</button>
<a href="{{ route('reserves') }}" class="btn btn-default btn-sm">戻る</a>
</div>
{{-- GET と同一ルートで POST 更新 --}} {{-- GET と同一ルートで POST 更新 --}}
<form id="edit-form" method="post" action="{{ route('reserves_edit', ['reserve_id'=>$row->reserve_id]) }}"> <form id="edit-form" method="post" action="{{ route('reserves_edit', ['reserve_id'=>$row->reserve_id]) }}">
@csrf @csrf
<div class="card-body">
<div class="card-body"> <div class="field">
<div class="row"> <label class="label">定期予約ID</label>
{{-- 左カラム(目标图顺序) --}} <div class="input">
<div class="col-lg-6"> <input type="text" class="form-control" value="{{ $row->reserve_id }}" readonly>
{{-- 定期予約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>
</div>
{{-- 右カラム(目标图顺序) --}} <div class="field">
<div class="col-lg-6"> <label class="label">定期契約ID</label>
{{-- 減免措置 --}} <div class="input">
<div class="field"> <input type="text" name="contract_id" class="form-control" placeholder="定期契約ID"
<label class="label">減免措置</label> value="{{ old('contract_id', $row->contract_id ?? '') }}" readonly>
<div class="input"> </div>
@php $reduction = old('reduction', $row->reduction ?? ''); @endphp </div>
<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">
<div class="field"> <label class="label">定期契約日時</label>
<label class="label">自動リマインド日</label> <div class="input">
<div class="input"> <input type="text" name="contract_created_at" class="form-control" placeholder="yyyy/mm/dd hh:mm:ss"
<input type="text" name="auto_remind_date" class="form-control" placeholder="yyyy/mm/dd" value="{{ old('contract_created_at', $row->contract_created_at ?? '') }}">
value="{{ old('auto_remind_date', $row->auto_remind_date ?? '') }}"> </div>
</div> </div>
</div>
{{-- 手動リマインド日 --}} <div class="field">
<div class="field"> <label class="label">利用者分類ID</label>
<label class="label">手動リマインド日</label> <div class="input">
<div class="input"> <select name="user_categoryid" class="form-control">
<input type="text" name="manual_remind_date" class="form-control" placeholder="yyyy/mm/dd" <option value="">全て</option>
value="{{ old('manual_remind_date', $row->manual_remind_date ?? '') }}"> @foreach(($userTypeOptions ?? []) as $k => $v)
</div> <option value="{{ $k }}" {{ (string)old('user_categoryid', $row->user_categoryid ?? '') === (string)$k ? 'selected' : '' }}>
</div> {{ $v }}
</option>
@endforeach
</select>
</div>
</div>
{{-- 800M以内フラグ --}} <div class="field">
<div class="field"> <label class="label">利用者ID<span class="req">*</span></label>
<label class="label">800M以内フラグ</label> <div class="input">
<div class="input"> @php
@php $m800 = old('within_800m_flag', $row->within_800m_flag ?? ''); @endphp $selectedUserId = old('user_id', $row->user_id ?? '');
<label class="mr-3"><input type="radio" name="within_800m_flag" value="1" {{ (string)$m800==='1'?'checked':'' }}> M以内</label> $selectedUserLabel = $selectedUserId !== '' ? ($userOptions[$selectedUserId] ?? $selectedUserId) : '';
<label><input type="radio" name="within_800m_flag" value="0" {{ (string)$m800==='0'?'checked':'' }}> M以内ではない</label> @endphp
</div> <input type="text" class="form-control" value="{{ $selectedUserLabel }}" readonly>
</div> <input type="hidden" name="user_id" value="{{ $selectedUserId }}">
</div>
</div>
{{-- 解約日 --}} <div class="field">
<div class="field"> <label class="label">予約日時<span class="req">*</span></label>
<label class="label">解約日</label> <div class="input">
<div class="input"> <input type="text" name="reserve_date" class="form-control" placeholder="yyyy/mm/dd hh:mm:ss"
<input type="text" name="contract_cancelday" class="form-control" placeholder="yyyy/mm/dd" value="{{ old('reserve_date', $row->reserve_date ?? '') }}">
value="{{ old('contract_cancelday', $row->contract_cancelday ?? '') }}"> </div>
</div> </div>
</div>
{{-- 有効フラグ --}} <div class="field">
<div class="field"> <label class="label">駐輪場ID<span class="req">*</span></label>
<label class="label">有効フラグ</label> <div class="input">
<div class="input"> <select name="park_id" class="form-control" required>
@php $valid = old('valid_flag', $row->valid_flag ?? ''); @endphp <option value="">選択してください</option>
<label class="mr-3"><input type="radio" name="valid_flag" value="1" {{ (string)$valid==='1'?'checked':'' }}> 有効</label> @foreach(($parkOptions ?? []) as $k => $v)
<label><input type="radio" name="valid_flag" value="0" {{ (string)$valid==='0'?'checked':'' }}> 無効</label> <option value="{{ $k }}" {{ (string)old('park_id', $row->park_id ?? '') === (string)$k ? 'selected' : '' }}>
</div> {{ $v }}
</div> </option>
@endforeach
</select>
</div>
</div>
{{-- 空き待ちメール送信日時 --}} <div class="field">
<div class="field"> <label class="label">駐輪場所ID<span class="req">*</span></label>
<label class="label">空き待ちメール送信日時</label> <div class="input">
<div class="input"> <select name="price_parkplaceid" class="form-control" required>
<input type="text" name="mail_sent_at" class="form-control" placeholder="yyyy/mm/dd hh:mm:ss" <option value="">選択してください</option>
value="{{ old('mail_sent_at', $row->mail_sent_at ?? '') }}"> @foreach(($parkplaceOptions ?? []) as $k => $v)
</div> <option value="{{ $k }}" {{ (string)old('price_parkplaceid', $row->price_parkplaceid ?? '') === (string)$k ? 'selected' : '' }}>
</div> {{ $v }}
</option>
@endforeach
</select>
</div>
</div>
{{-- 手動通知 --}} <div class="field">
<div class="field"> <label class="label">車種区分ID</label>
<label class="label">手動通知</label> <div class="input">
<div class="input"> <select name="psection_id" class="form-control">
@php $mnotice = old('manual_notice', $row->manual_notice ?? ''); @endphp <option value="">選択してください</option>
<label class="mr-3"><input type="radio" name="manual_notice" value="0" {{ (string)$mnotice==='0'?'checked':'' }}> 手動通知</label> @foreach(($psectionOptions ?? []) as $k => $v)
<label><input type="radio" name="manual_notice" value="1" {{ (string)$mnotice==='1'?'checked':'' }}> メール通知</label> <option value="{{ $k }}" {{ (string)old('psection_id', $row->psection_id ?? '') === (string)$k ? 'selected' : '' }}>
</div> {{ $v }}
</div> </option>
@endforeach
</select>
</div>
</div>
{{-- 手動通知方法 --}} <div class="field">
<div class="field"> <label class="label">駐輪分類ID</label>
<label class="label">手動通知方法</label> <div class="input">
<div class="input"> <select name="ptype_id" class="form-control">
@php $mhow = old('manual_notice_method', $row->manual_notice_method ?? ''); @endphp <option value="">選択してください</option>
<label class="mr-3"><input type="radio" name="manual_notice_method" value="tel" {{ $mhow==='tel'?'checked':'' }}> 電話</label> @foreach(($ptypeOptions ?? []) as $k => $v)
<label><input type="radio" name="manual_notice_method" value="post" {{ $mhow==='post'?'checked':'' }}> 郵送</label> <option value="{{ $k }}" {{ (string)old('ptype_id', $row->ptype_id ?? '') === (string)$k ? 'selected' : '' }}>
<div class="help-text mt-1"> 必要に応じて選択肢は調整してください。</div> {{ $v }}
</div> </option>
</div> @endforeach
</select>
</div>
</div>
{{-- 空き待ち順 --}} <div class="field">
<div class="field"> <label class="label">減免措置</label>
<label class="label">空き待ち順</label> <div class="input">
<div class="input"> @php $reduction = old('reduction', $row->reduction ?? ''); @endphp
<input type="number" name="waitlist_order" class="form-control" min="0" step="1" <label class="radio-inline">
value="{{ old('waitlist_order', $row->waitlist_order ?? '') }}"> <input type="radio" name="reduction" value="1" {{ (string)$reduction === '1' ? 'checked' : '' }}> あり
</div> </label>
</div> <label class="radio-inline">
<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>
<div class="field">
<label class="label">800M以内フラグ</label>
<div class="input">
@php $m800 = old('within_800m_flag', $row->within_800m_flag ?? ''); @endphp
<label class="radio-inline">
<input type="radio" name="within_800m_flag" value="1" {{ (string)$m800 === '1' ? 'checked' : '' }}> M以内
</label>
<label class="radio-inline">
<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="radio-inline">
<input type="radio" name="valid_flag" value="1" {{ (string)$valid === '1' ? 'checked' : '' }}> 有効
</label>
<label class="radio-inline">
<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="radio-inline">
<input type="radio" name="manual_notice" value="0" {{ (string)$mnotice === '0' ? 'checked' : '' }}> 手動通知
</label>
<label class="radio-inline">
<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="radio-inline">
<input type="radio" name="manual_notice_method" value="tel" {{ $mhow === 'tel' ? 'checked' : '' }}> 電話
</label>
<label class="radio-inline">
<input type="radio" name="manual_notice_method" value="post" {{ $mhow === 'post' ? 'checked' : '' }}> 郵送
</label>
</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" placeholder="空き待ち順"
value="{{ old('waitlist_order', $row->waitlist_order ?? '') }}">
</div> </div>
</div> </div>
</div> </div>
{{-- 下部操作(保留:目标图底部有登録/削除) --}} {{-- 下部操作(参照画面の下部にも登録/削除ボタンあり --}}
<div class="card-footer d-flex justify-content-start"> <div class="card-footer">
<button type="submit" class="btn btn-success">登録</button> <button type="submit" class="btn btn-default btn-sm js-confirm-submit">登録</button>
<button type="button" id="btnDeleteBottom" class="btn btn-danger ml-2">削除</button> <button type="button" id="btnDeleteBottom" class="btn btn-default btn-sm">削除</button>
<a href="{{ route('reserves') }}" class="btn btn-default ml-2">戻る</a> <a href="{{ route('reserves') }}" class="btn btn-default btn-sm">戻る</a>
</div> </div>
</form> </form>
{{-- 削除POSTconfirmed + ids[] --}} {{-- 削除POSTconfirmed + ids[] --}}
<form id="del-form" method="post" action="{{ route('reserves_delete') }}" style="display:none;"> <form id="del-form" method="post" action="{{ route('reserves_delete') }}" style="display:none;">
@ -331,10 +379,43 @@
<script> <script>
(function(){ (function(){
function del(){ if(confirm('この予約を削除します。よろしいですか?')) document.getElementById('del-form').submit(); } var editForm = document.getElementById('edit-form');
var t=document.getElementById('btnDeleteTop'), b=document.getElementById('btnDeleteBottom');
if(t) t.addEventListener('click', del); function handleSubmitConfirm(event){
if(b) b.addEventListener('click', del); event.preventDefault();
var formAttr = this.getAttribute('form');
var targetForm = this.form || (formAttr ? document.getElementById(formAttr) : editForm);
if (!targetForm) { return; }
var submitAction = function(){ targetForm.submit(); };
if (window.jQuery && typeof window.jQuery.confirm === 'function') {
window.jQuery.confirm({
title: '確認ダイアログ。',
content: '!登録してよろしいですか? はい/いいえ',
buttons: {
ok: { text: 'はい', btnClass: 'btn-primary', keys: ['enter'], action: submitAction },
いいえ: function () {}
}
});
} else if (window.confirm('!登録してよろしいですか? はい/いいえ')) {
submitAction();
}
}
var submitButtons = document.querySelectorAll('.js-confirm-submit');
Array.prototype.forEach.call(submitButtons, function(btn){
btn.addEventListener('click', handleSubmitConfirm);
});
function handleDelete(){
if(window.confirm('削除してよろしいですか? はい/いいえ')){
document.getElementById('del-form').submit();
}
}
var topBtn = document.getElementById('btnDeleteTop');
var bottomBtn = document.getElementById('btnDeleteBottom');
if(topBtn){ topBtn.addEventListener('click', handleDelete); }
if(bottomBtn){ bottomBtn.addEventListener('click', handleDelete); }
})(); })();
</script> </script>
@endsection @endsection

View File

@ -25,8 +25,26 @@
/* 一覧テーブル:斑馬(ゼブラ)無し、やや詰め気味 */ /* 一覧テーブル:斑馬(ゼブラ)無し、やや詰め気味 */
.rv-table th,.rv-table td{padding:.35rem .5rem;font-size:12px;} .rv-table th,.rv-table td{padding:.35rem .5rem;font-size:12px;}
.rv-table thead th{white-space:nowrap;background:#eeeeee;} /* ← 表頭:灰色 */ .rv-table thead th{white-space:nowrap;background:#eeeeee;}
.card .card-header{background:#f5f5f5;} /* ← カード見出しも淡いグレー */ .rv-table thead th.sortable{cursor:pointer;text-decoration:none;}
.rv-table thead th,
.rv-table thead th .sort-icon,
.rv-table thead th .sort-icon .up,
.rv-table thead th .sort-icon .down{
text-decoration:none !important;
}
.rv-table thead th.sorting_asc .sort-icon .up,
.rv-table thead th.sorting_desc .sort-icon .down{color:#000;}
.rv-table thead th .sort-icon{
display:inline-flex;
align-items:center;
flex-direction:row;
gap:2px;
font-size:11px;
color:#b5b5b5;
letter-spacing: -5px; /* ↑↓を詰める */
text-decoration: none; /* _削除 */
}
/* ツールバー:左にボタン群、右にページャ */ /* ツールバー:左にボタン群、右にページャ */
.rv-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;} .rv-toolbar{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;}
@ -34,6 +52,7 @@
/* 操作セルの背景色(定期契約マスタと同じ雰囲気) */ /* 操作セルの背景色(定期契約マスタと同じ雰囲気) */
.op-cell{background:#faebd7;} .op-cell{background:#faebd7;}
</style> </style>
<div class="rv-page"> <div class="rv-page">
@ -154,34 +173,45 @@
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered table-hover rv-table mb-0 text-nowrap"> <table class="table table-bordered table-hover rv-table mb-0 text-nowrap">
<thead> <thead>
@php
$currentSort = $sort ?? 'reserve_id';
$currentDir = strtolower($sort_type ?? 'asc');
if (!in_array($currentDir, ['asc','desc'], true)) { $currentDir = 'asc'; }
$sortClass = function(string $key) use ($currentSort, $currentDir) {
if ($currentSort === $key) {
return 'sortable sorting_' . $currentDir;
}
return 'sortable sorting';
};
$renderSortIcon = function() {
return '<span class="sort-icon"><span class="up">↑</span><span class="down">↓</span></span>';
};
@endphp
<tr> <tr>
{{-- 操作(全選択チェック+編集)※表頭は灰色 --}}
<th style="width:140px;"> <th style="width:140px;">
<input type="checkbox" id="chkAll"> <input type="checkbox" id="chkAll">
<span class="ml-1"></span> <span class="ml-1"></span>
</th> </th>
<th class="{{ $sortClass('reserve_id') }}" data-sort="reserve_id">定期予約ID {!! $renderSortIcon() !!}</th>
{{-- 要求どおりの見出し(順番も完全一致) --}} <th class="{{ $sortClass('contract_id') }}" data-sort="contract_id">定期契約ID {!! $renderSortIcon() !!}</th>
<th>定期予約ID</th> <th class="{{ $sortClass('contract_created_at') }}" data-sort="contract_created_at">定期契約日時 {!! $renderSortIcon() !!}</th>
<th>定期契約ID</th> <th class="{{ $sortClass('user_categoryid') }}" data-sort="user_categoryid">利用者分類ID {!! $renderSortIcon() !!}</th>
<th>定期契約日時</th> <th class="{{ $sortClass('user_id') }}" data-sort="user_id">利用者ID {!! $renderSortIcon() !!}</th>
<th>利用者分類ID</th> <th class="{{ $sortClass('reserve_date') }}" data-sort="reserve_date">予約日時 {!! $renderSortIcon() !!}</th>
<th>利用者ID</th> <th class="{{ $sortClass('park_price_name') }}" data-sort="park_price_name">駐輪場ID {!! $renderSortIcon() !!}</th>
<th>予約日時</th> <th class="{{ $sortClass('price_parkplaceid') }}" data-sort="price_parkplaceid">駐輪場所ID {!! $renderSortIcon() !!}</th>
<th>駐輪場ID</th> <th class="{{ $sortClass('psection_subject') }}" data-sort="psection_subject">車種区分ID {!! $renderSortIcon() !!}</th>
<th>駐輪場所ID</th> <th class="{{ $sortClass('ptype_subject') }}" data-sort="ptype_subject">駐輪分類ID {!! $renderSortIcon() !!}</th>
<th>車種区分ID</th> <th class="{{ $sortClass('reserve_reduction') }}" data-sort="reserve_reduction">減免措置 {!! $renderSortIcon() !!}</th>
<th>駐輪分類ID</th> <th class="{{ $sortClass('reserve_auto_remind') }}" data-sort="reserve_auto_remind">自動リマインド日 {!! $renderSortIcon() !!}</th>
<th>減免措置</th> <th class="{{ $sortClass('reserve_manual_remind') }}" data-sort="reserve_manual_remind">手動リマインド日 {!! $renderSortIcon() !!}</th>
<th>自動リマインド日</th> <th class="{{ $sortClass('flag_800m') }}" data-sort="flag_800m">800M以内フラグ {!! $renderSortIcon() !!}</th>
<th>手動リマインド日</th> <th class="{{ $sortClass('reserve_cancelday') }}" data-sort="reserve_cancelday">解約日 {!! $renderSortIcon() !!}</th>
<th>800M以内フラグ</th> <th class="{{ $sortClass('valid_flag') }}" data-sort="valid_flag">有効フラグ {!! $renderSortIcon() !!}</th>
<th>解約日</th> <th class="{{ $sortClass('sent_date') }}" data-sort="sent_date">メール送信日時 {!! $renderSortIcon() !!}</th>
<th>有効フラグ</th> <th class="{{ $sortClass('reserve_manual') }}" data-sort="reserve_manual">手動通知 {!! $renderSortIcon() !!}</th>
<th>メール送信日時</th> <th class="{{ $sortClass('reserve_notice') }}" data-sort="reserve_notice">手動通知方法 {!! $renderSortIcon() !!}</th>
<th>手動通知</th> <th class="{{ $sortClass('reserve_order') }}" data-sort="reserve_order">空き待ち順 {!! $renderSortIcon() !!}</th>
<th>手動通知方法</th>
<th>空き待ち順</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -200,23 +230,40 @@
<td class="text-right">{{ $row->reserve_id }}</td> {{-- 定期予約ID --}} <td class="text-right">{{ $row->reserve_id }}</td> {{-- 定期予約ID --}}
<td class="text-right">{{ $row->contract_id ?? '' }}</td> {{-- 定期契約ID --}} <td class="text-right">{{ $row->contract_id ?? '' }}</td> {{-- 定期契約ID --}}
<td>{{ $row->contract_created_at ?? '' }}</td> {{-- 定期契約日時 --}} <td>{{ $row->contract_created_at ?? '' }}</td> {{-- 定期契約日時 --}}
<td class="text-right">{{ $row->user_categoryid ?? '' }}</td> {{-- 利用者分類ID --}} <td>
<td class="text-right">{{ $row->user_id }}</td> {{-- 利用者ID --}} @php
$subjects = array_values(array_filter([
$row->usertype_subject1 ?? '',
$row->usertype_subject2 ?? '',
$row->usertype_subject3 ?? '',
], fn($value) => $value !== ''));
@endphp
{{ $subjects ? implode('/', $subjects) : '' }}
</td> {{-- 利用者分類ID分類名// 表示) --}}
<td>{{ trim(($row->user_id ?? '') . ' ' . ($row->user_name ?? '')) }}</td> {{-- 利用者IDID 名字) --}}
<td>{{ $row->reserve_date ?? '' }}</td> {{-- 予約日時 --}} <td>{{ $row->reserve_date ?? '' }}</td> {{-- 予約日時 --}}
<td class="text-right">{{ $row->park_id ?? '' }}</td> {{-- 駐輪場ID --}} <td>{{ trim($row->park_name ?? '') }}</td> {{-- 駐輪場ID --}}
<td class="text-right">{{ $row->price_parkplaceid ?? '' }}</td> {{-- 駐輪場所ID --}} <td>{{ $row->display_prine_name ?? '' }}</td> {{-- 駐輪場所ID --}}
<td class="text-right">{{ $row->psection_id ?? '' }}</td> {{-- 車種区分ID --}} <td>{{ $row->psection_subject ?? '' }}</td> {{-- 車種区分ID区分名を表示 --}}
<td class="text-right">{{ $row->ptype_id ?? '' }}</td> {{-- 駐輪分類ID --}} <td>{{ $row->ptype_subject ?? '' }}</td> {{-- 駐輪分類IDptype_subject 表示 --}}
<td>{{ $row->reduction ?? '' }}</td> {{-- 減免措置 --}} <td>{{ $row->reserve_reduction ?? '' }}</td> {{-- 減免措置 --}}
<td>{{ $row->auto_remind_date ?? '' }}</td> {{-- 自動リマインド日 --}} <td>{{ $row->reserve_auto_remind ?? '' }}</td> {{-- 自動リマインド日 --}}
<td>{{ $row->manual_remind_date ?? '' }}</td> {{-- 手動リマインド日 --}} <td>{{ $row->reserve_manual_remind ?? '' }}</td> {{-- 手動リマインド日 --}}
<td>{{ isset($row->within_800m_flag) ? (($row->within_800m_flag)?'有':'無') : '' }}</td> {{-- 800M以内フラグ --}} <td>{{ $row->flag_800m ?? '' }}</td> {{-- 800M以内フラグ --}}
<td>{{ $row->contract_cancelday ?? '' }}</td> {{-- 解約日 --}} <td>{{ $row->reserve_cancelday ?? '' }}</td> {{-- 解約日 --}}
<td>{{ isset($row->valid_flag) ? (($row->valid_flag)?'有効':'無効') : '' }}</td> {{-- 有効フラグ --}} <td>
<td>{{ $row->mail_sent_at ?? '' }}</td> {{-- メール送信日時 --}} @if((string)$row->valid_flag === '1')
<td>{{ isset($row->manual_notice) ? (($row->manual_notice)?'有':'無') : '' }}</td> {{-- 手動通知 --}} 有効
<td>{{ $row->manual_notice_method ?? '' }}</td> {{-- 手動通知方法 --}} @elseif((string)$row->valid_flag === '0')
<td class="text-right">{{ $row->waitlist_order ?? '' }}</td> {{-- 空き待ち順 --}} 無効
@else
{{ $row->valid_flag ?? '' }}
@endif
</td> {{-- 有効フラグ --}}
<td>{{ $row->sent_date ?? '' }}</td> {{-- メール送信日時 --}}
<td>{{ $row->reserve_manual ?? '' }}</td> {{-- 手動通知 --}}
<td>{{ $row->reserve_notice ?? '' }}</td> {{-- 手動通知方法 --}}
<td class="text-right">{{ $row->reserve_order ?? '' }}</td> {{-- 空き待ち順 --}}
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>
@ -236,9 +283,13 @@
{{-- 一括削除のフロント処理jQuery不要 --}} {{-- 一括削除のフロント処理jQuery不要 --}}
<script> <script>
(function(){ (function(){
// 全選択チェック
var chkAll = document.getElementById('chkAll'); var chkAll = document.getElementById('chkAll');
var chks = document.getElementsByClassName('chkRow'); var chks = document.getElementsByClassName('chkRow');
var filterForm = document.getElementById('filter-form');
var sortInput = document.getElementById('sort');
var sortTypeInput = document.getElementById('sort_type');
// 全選択チェック
if (chkAll) { if (chkAll) {
chkAll.addEventListener('change', function(){ chkAll.addEventListener('change', function(){
Array.prototype.forEach.call(chks, function(c){ c.checked = chkAll.checked; }); Array.prototype.forEach.call(chks, function(c){ c.checked = chkAll.checked; });
@ -253,11 +304,44 @@
var any = false; var any = false;
Array.prototype.forEach.call(chks, function(c){ if (c.checked) any = true; }); Array.prototype.forEach.call(chks, function(c){ if (c.checked) any = true; });
if (!any) { alert('削除対象の行を選択してください。'); return; } if (!any) { alert('削除対象の行を選択してください。'); return; }
if (confirm('選択した予約を削除します。よろしいですか?')) {
form.submit(); var submitDelete = function () { form.submit(); };
if (window.jQuery && typeof window.jQuery.confirm === 'function') {
window.jQuery.confirm({
title: '確認ダイアログ。',
content: '削除してよろしいですか? はい/いいえ',
buttons: {
ok: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: submitDelete
},
いいえ: function () {}
}
});
} else if (confirm('削除してよろしいですか? はい/いいえ')) {
submitDelete();
} }
}); });
} }
var sortHeaders = document.querySelectorAll('th[data-sort]');
if (sortHeaders.length && filterForm && sortInput && sortTypeInput) {
Array.prototype.forEach.call(sortHeaders, function(th){
th.addEventListener('click', function(){
var key = th.getAttribute('data-sort');
if (!key) { return; }
var nextDir = 'asc';
if (sortInput.value === key) {
nextDir = sortTypeInput.value === 'asc' ? 'desc' : 'asc';
}
sortInput.value = key;
sortTypeInput.value = nextDir;
filterForm.submit();
});
});
}
})(); })();
</script> </script>
@endsection @endsection