シール再発行、タグ再発行機能追加 #34

Merged
y.higashide merged 1 commits from main_higashide into main 2025-10-01 13:04:27 +09:00
10 changed files with 424 additions and 27 deletions
Showing only changes of commit d677aa232d - Show all commits

View File

@ -0,0 +1,96 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
class SealReissueController extends Controller
{
public function index($contract_id)
{
$user_id = session('user_id');
if (!$user_id) {
return redirect('/login');
}
$user_name = DB::table('user')->where('user_id', $user_id)->value('user_name');
$contract = DB::table('regular_contract')
->join('park', 'regular_contract.park_id', '=', 'park.park_id')
->where('contract_id', $contract_id)
->select('regular_contract.contract_id', 'park.park_name')
->first();
\Log::info('シール再発行確認画面にアクセス', [
'user_id' => $user_id,
]);
return view('regular_contract.seal_reissue', [
'contract' => $contract,
'active_menu' => 'SWC-1-1', // マイページメニューの選択状態用
'user_name' => $user_name ? $user_name : '', // ユーザー名(ヘッダー用)
]);
}
public function reason($contract_id)
{
$user_id = session('user_id');
if (!$user_id) {
return redirect('/login');
}
$user_name = DB::table('user')->where('user_id', $user_id)->value('user_name');
\Log::info('シール再発行理由入力画面にアクセス', [
'user_id' => $user_id,
]);
return view('regular_contract.seal_reissue_reason', [
'contract_id' => $contract_id,
'active_menu' => 'SWC-1-1', // マイページメニューの選択状態用
'user_name' => $user_name ? $user_name : '', // ユーザー名(ヘッダー用)
]);
}
public function complete(Request $request, $contract_id)
{
$user_id = session('user_id');
if (!$user_id) {
return redirect('/login');
}
$user_name = DB::table('user')->where('user_id', $user_id)->value('user_name');
$validated = $request->validate([
'reason' => ['required'],
'other_reason' => [
'nullable',
'string',
'max:255',
'regex:/^[\x20-\x7Eぁ-んァ-ヶ一-龠々ーa-zA-Z0-9---Z、。・「」『』()【】[]{}〈〉《》!?:;…ー~\s\r\n]+$/u',
'required_if:reason,その他'
],
], [
'reason.required' => '理由を選択してください。',
'other_reason.max' => 'その他の理由は255文字以内で入力してください。',
'other_reason.regex' => 'その他の理由に使用できない文字が含まれています。',
'other_reason.required_if' => 'その他を選択した場合は理由を入力してください。'
]);
$contract = DB::table('regular_contract')
->join('park', 'regular_contract.park_id', '=', 'park.park_id')
->where('contract_id', $contract_id)
->select('regular_contract.contract_id', 'park.park_name')
->first();
$reason = $request->input('reason');
$other_reason = $request->input('other_reason');
\Log::info('シール再発行申請完了画面にアクセス', [
'user_id' => $user_id,
]);
return view('regular_contract.seal_reissue_complete', [
'active_menu' => 'SWC-4-1', // マイページメニューの選択状態用
'user_name' => $user_name ? $user_name : '', // ユーザー名(ヘッダー用)
'contract' => $contract
]);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
class UserTagReissueController extends Controller
{
public function index()
{
$user_id = session('user_id');
if (!$user_id) {
return redirect('/login');
}
$user = DB::table('user')->where('user_id', $user_id)->first();
\Log::info('タグ再発行申請画面にアクセス', [
'user_id' => $user_id,
]);
return view('user.tag_reissue', [
'user' => $user,
'active_menu' => 'SWC-1-1', // マイページメニューの選択状態用
'user_name' => $user ? $user->user_name : '', // ユーザー名(ヘッダー用)
]);
}
public function complete()
{
$user_id = session('user_id');
if (!$user_id) {
return redirect('/login');
}
$user = DB::table('user')->where('user_id', $user_id)->first();
\Log::info('タグ再発行申請完了画面にアクセス', [
'user_id' => $user_id,
]);
return view('user.tag_reissue_complete', [
'active_menu' => 'SWC-1-1', // マイページメニューの選択状態用
'user_name' => $user ? $user->user_name : '', // ユーザー名(ヘッダー用)
]);
}
}

View File

@ -262,26 +262,35 @@ return null;
<button type="button" id="cancelModalBtn" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;" data-bs-toggle="modal" data-bs-target="#cancelModal">解約について</button> <button type="button" id="cancelModalBtn" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;" data-bs-toggle="modal" data-bs-target="#cancelModal">解約について</button>
@endif @endif
</div> </div>
@php <div style="display: flex; gap: 6px;">
$has_receipt = DB::table('inv_publish')->where('contract_id', $contract->contract_id)->exists(); @php
@endphp $has_receipt = DB::table('inv_publish')->where('contract_id', $contract->contract_id)->exists();
@if($has_receipt) @endphp
@if($bg == 'alert-warning') @if($has_receipt)
<a href="{{ url('receipt/download/' . $contract->contract_id) }}" class="btn btn-outline-warning badge-pill custom-rounded-btn" style="background: transparent;">領収書再発行</a> @if($bg == 'alert-warning')
@elseif($bg == 'alert-danger') <a href="{{ url('receipt/download/' . $contract->contract_id) }}" class="btn btn-outline-warning badge-pill custom-rounded-btn" style="background: transparent;">領収書再発行</a>
<a href="{{ url('receipt/download/' . $contract->contract_id) }}" class="btn btn-outline-danger badge-pill custom-rounded-btn" style="background: transparent;">領収書再発行</a> @elseif($bg == 'alert-danger')
@else <a href="{{ url('receipt/download/' . $contract->contract_id) }}" class="btn btn-outline-danger badge-pill custom-rounded-btn" style="background: transparent;">領収書再発行</a>
<a href="{{ url('receipt/download/' . $contract->contract_id) }}" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;">領収書再発行</a> @else
@endif <a href="{{ url('receipt/download/' . $contract->contract_id) }}" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;">領収書再発行</a>
@else @endif
@if($bg == 'alert-warning') @else
<a href="{{ url('receipt/input/' . $contract->contract_id) }}" class="btn btn-outline-warning badge-pill custom-rounded-btn" style="background: transparent;">領収書発行</a> @if($bg == 'alert-warning')
@elseif($bg == 'alert-danger') <a href="{{ url('receipt/input/' . $contract->contract_id) }}" class="btn btn-outline-warning badge-pill custom-rounded-btn" style="background: transparent;">領収書発行</a>
<a href="{{ url('receipt/input/' . $contract->contract_id) }}" class="btn btn-outline-danger badge-pill custom-rounded-btn" style="background: transparent;">領収書発行</a> @elseif($bg == 'alert-danger')
@else <a href="{{ url('receipt/input/' . $contract->contract_id) }}" class="btn btn-outline-danger badge-pill custom-rounded-btn" style="background: transparent;">領収書発行</a>
<a href="{{ url('receipt/input/' . $contract->contract_id) }}" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;">領収書発行</a> @else
@endif <a href="{{ url('receipt/input/' . $contract->contract_id) }}" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;">領収書発行</a>
@endif @endif
@endif
@if($bg == 'alert-warning')
<a href="{{ url('seal/reissue/' . $contract->contract_id) }}" class="btn btn-outline-warning badge-pill custom-rounded-btn" style="background: transparent;">シール再発行</a>
@elseif($bg == 'alert-danger')
<a href="{{ url('seal/reissue/' . $contract->contract_id) }}" class="btn btn-outline-danger badge-pill custom-rounded-btn" style="background: transparent;">シール再発行</a>
@else
<a href="{{ url('seal/reissue/' . $contract->contract_id) }}" class="btn btn-outline-secondary badge-pill custom-rounded-btn" style="background: transparent;">シール再発行</a>
@endif
</div>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -0,0 +1,27 @@
@extends('layouts.app')
@section('content')
<main>
<header class="alert alert-success">
<h4 class="container">定期契約情報確認 > シール再発行</h4>
</header>
<section id="" class="container mt30 mb50">
<div class="col-12 col-md-8 offset-0 offset-md-2 mb30">
<h3 class="text-center alert-success">選択した駐輪場</h3>
</div>
<div class="col-12 col-md-8 offset-0 offset-md-2 mb30">
<h3 class="text-center alert-warning">
<span class="small">定期契約ID: {{ $contract->contract_id }}<br>{{ $contract->park_name }}</span>
</h3>
<p class="text-center"><br>こちらのシールを再発行します。<br>よろしいですか?</p>
</div>
<div class="row">
<div class="col-12 col-md-5 offset-md-1 mt10">
<a href="{{ url('regular_contract/info') }}" class="btn btn-lg btn-block btn-outline-success">戻る</a>
</div>
<div class="col-12 col-md-5 mt10">
<a href="{{ url('seal/reissue/reason/' . $contract->contract_id) }}" class="btn btn-lg btn-block btn-success">進む</a>
</div>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,20 @@
@extends('layouts.app')
@section('content')
<main>
<header class="alert alert-success">
<h4 class="container">定期契約情報確認 > シール再発行</h4>
</header>
<section id="" class="container mt30 mb50">
<div class="col-12 col-md-8 offset-0 offset-md-2 mb30">
<h3 class="text-center alert-warning">
<span class="small">定期契約ID: {{ $contract->contract_id }}<br></span>
<span>{{ $contract->park_name }}</span>
</h3>
<p class="text-center"><br>こちらのシールの再発行準備が整いました。<br>上記駐輪場にてシールをお受け取りください。</p>
</div>
<div class="col-12 col-md-8 offset-0 offset-md-2 mb30">
<a href="{{ url('mypage') }}" class="btn btn-lg btn-block btn-outline-success">マイページへ戻る</a>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,86 @@
@extends('layouts.app')
@section('content')
<main>
<header class="alert alert-success">
<h4 class="container">ユーザー情報確認 > シール再発行理由</h4>
</header>
@if ($errors->any())
<div class="alert alert-danger text-center">
@foreach ($errors->all() as $error)
<div>{{ $error }}</div>
@endforeach
</div>
@endif
<section class="container mt30 mb50">
<div class="col-12 col-md-8 offset-0 offset-md-2 mb30">
<h2 class="text-center alert-success">再発行手続き</h2>
</div>
<form method="POST" action="{{ url('seal/reissue/complete/' . $contract_id) }}">
@csrf
<div class="col-12 col-md-8 offset-0 offset-md-2 mb30">
<div class="mb-4">
<div class="form-check">
<input class="form-check-input" type="radio" name="reason" id="reason1" value="自動車の買い換え">
<label class="form-check-label" for="reason1">自動車の買い換え</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="reason" id="reason2" value="汚損">
<label class="form-check-label" for="reason2">汚損</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="reason" id="reason3" value="盗難">
<label class="form-check-label" for="reason3">盗難</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="reason" id="reason4" value="その他">
<label class="form-check-label" for="reason4">その他</label>
</div>
</div>
<div class="mb-4" id="other-reason-area" style="display: none;">
<textarea class="form-control" name="other_reason" rows="4" maxlength="255"
placeholder="その他の場合、こちらへ理由をご入力ください" style="resize: none;"></textarea>
<div class="text-right small"><span id="char-count">0</span>/255</div>
</div>
<div class="mb-4">
【再発行に関する注意事項】<br>
2回以上の再発行には別途手続きが必要です。<br>
紛失にはご注意ください。
</div>
</div>
<div class="row">
<div class="col-12 col-md-5 offset-md-1 mt10">
<a href="{{ url('seal_reissue/' . $contract_id) }}" class="btn btn-lg btn-block btn-outline-success">戻る</a>
</div>
<div class="col-12 col-md-5 mt10">
<button type="submit" class="btn btn-lg btn-block btn-success">進む</button>
</div>
</div>
</form>
</section>
</main>
<script>
document.addEventListener('DOMContentLoaded', function() {
// ラジオボタンの選択でテキストエリア表示切替
const radios = document.querySelectorAll('input[name="reason"]');
const otherArea = document.getElementById('other-reason-area');
radios.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'その他') {
otherArea.style.display = '';
} else {
otherArea.style.display = 'none';
}
});
});
// 文字数カウント
const textarea = document.querySelector('textarea[name="other_reason"]');
const charCount = document.getElementById('char-count');
if (textarea) {
textarea.addEventListener('input', function() {
charCount.textContent = this.value.length;
});
}
});
</script>
@endsection

View File

@ -3,9 +3,9 @@
@section('content') @section('content')
<main> <main>
@if (session('success')) @if (session('success'))
<div class="alert alert-success"> <div class="alert alert-success">
{{ session('success') }} {{ session('success') }}
</div> </div>
@endif @endif
<header class="alert alert-success"> <header class="alert alert-success">
<h4 class="container">ユーザー情報確認 > ユーザー情報</h4> <h4 class="container">ユーザー情報確認 > ユーザー情報</h4>
@ -87,9 +87,9 @@
</div> </div>
<div class="col-12 col-lg-6 mb10"> <div class="col-12 col-lg-6 mb10">
@if(!empty($user->photo_filename1)) @if(!empty($user->photo_filename1))
<h3><img src="{{ asset('storage/photo/' . $user->photo_filename1) }}"></h3> <h3><img src="{{ asset('storage/photo/' . $user->photo_filename1) }}"></h3>
@else @else
<h3></h3> <h3></h3>
@endif @endif
</div> </div>
<div class="col-12 col-md-3 offset-0 offset-md-2"> <div class="col-12 col-md-3 offset-0 offset-md-2">
@ -97,9 +97,9 @@
</div> </div>
<div class="col-12 col-lg-6 mb10"> <div class="col-12 col-lg-6 mb10">
@if(!empty($user->photo_filename2)) @if(!empty($user->photo_filename2))
<h3><img src="{{ asset('storage/photo/' . $user->photo_filename2) }}"></h3> <h3><img src="{{ asset('storage/photo/' . $user->photo_filename2) }}"></h3>
@else @else
<h3></h3> <h3></h3>
@endif @endif
</div> </div>
<div class="col-12 col-md-3 offset-0 offset-md-2"> <div class="col-12 col-md-3 offset-0 offset-md-2">
@ -114,6 +114,9 @@
<div class="col-12 col-md-5 mt10"> <div class="col-12 col-md-5 mt10">
<a class="btn btn-lg btn-block btn-outline-success" href="{{ url('/user/withdraw') }}">退会する</a> <a class="btn btn-lg btn-block btn-outline-success" href="{{ url('/user/withdraw') }}">退会する</a>
</div> </div>
<div class="col-12 col-md-4 offset-0 offset-md-4 mt50 mb50">
<a class="btn btn-lg btn-block btn-success" href="{{ url('/user/tag_reissue') }}">タグの再発行を行う</a>
</div>
</form> </form>
</section> </section>
</main> </main>

View File

@ -0,0 +1,83 @@
@extends('layouts.app')
@section('content')
<main>
<header class="alert alert-success">
<h4 class="container">ユーザー情報確認 > タグ再発行申請</h4>
</header>
<section id="" class="container mt30 mb50">
<div class="alert alert-success text-center pt20 pb10 mb30">
<h5>タグ再発行を行うお客様の情報をご確認ください。</h5>
<p>住所、電話番号、メールアドレス等に変更がある場合、再発行を申請する前にユーザー情報確認から<br class="pc">お客様の情報を最新状態へ更新をお願いいたします。</p>
</div>
<div class="row">
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_name">お名前</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_name }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_phonetic">フリガナ</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_phonetic }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_gender">性別</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_gender ?? '未入力' }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_regident">居住所</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_regident_zip }}{{ $user->user_regident_pre }}{{ $user->user_regident_city }}{{ $user->user_regident_add }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_homephone">自宅電話番号</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_homephone ?? '未入力' }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_mobile">携帯電話番号</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_mobile ?? '未入力' }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_primemail">メールアドレス</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_primemail }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_submail">予備メールアドレス</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3>{{ $user->user_submail ?? '未入力' }}</h3>
</div>
<div class="col-12 col-md-3 offset-0 offset-md-1">
<label for="user_pass">パスワード</label>
</div>
<div class="col-12 col-lg-6 mb10">
<h3></h3>
</div>
<div class="col-12 col-md-5 offset-0 offset-md-1 mt10">
<a href="{{ url('/user/edit') }}" class="btn btn-lg btn-block btn-success">ユーザー情報を変更する</a>
</div>
<div class="col-12 col-md-5 mt10">
<a href="{{ url('/user/tag_reissue/complete') }}" class="btn btn-lg btn-block btn-outline-success">再発行申請する</a>
</div>
<div class="col-12 col-md-6 offset-0 offset-md-3 mt50 mb50">
<a href="{{ url('/mypage') }}" class="btn btn-lg btn-block btn-outline-success">マイページへ戻る</a>
</div>
</div>
</section>
</main>
@endsection

View File

@ -0,0 +1,17 @@
@extends('layouts.app')
@section('content')
<main>
<header class="alert alert-success">
<h4 class="container">ユーザー情報確認 > タグ再発行申請完了</h4>
</header>
<div class="row">
<div class="col-12 col-md-8 offset-0 offset-md-2 mt-4 mb30">
<h3 class="text-center">タグの再発行申請が完了しました。</h3>
<p class="mt30 text-center">現在オペレーターが確認中です。<br>タグの再発行までいましばらくお待ちください。</p>
<div class="col-12 col-md-6 offset-0 offset-md-3 mt50 mb50">
<a href="{{ url('/mypage') }}" class="btn btn-lg btn-block btn-outline-success">マイページへ戻る</a>
</div>
</div>
</div>
</main>
@endsection

View File

@ -16,11 +16,13 @@ use App\Http\Controllers\UserInfoController;
use App\Http\Controllers\UserEditController; use App\Http\Controllers\UserEditController;
use App\Http\Controllers\UserEditConfirmController; use App\Http\Controllers\UserEditConfirmController;
use App\Http\Controllers\UserWithdrawController; use App\Http\Controllers\UserWithdrawController;
use App\Http\Controllers\UserTagReissueController;
use App\Http\Controllers\RegularContractController; use App\Http\Controllers\RegularContractController;
use App\Http\Controllers\RegularContractCreateController; use App\Http\Controllers\RegularContractCreateController;
use App\Http\Controllers\ParkingSearchController; use App\Http\Controllers\ParkingSearchController;
use App\Http\Controllers\ParkWaitlistController; use App\Http\Controllers\ParkWaitlistController;
use App\Http\Controllers\ReceiptController; use App\Http\Controllers\ReceiptController;
use App\Http\Controllers\SealReissueController;
use App\Http\Controllers\ParkDetailController; use App\Http\Controllers\ParkDetailController;
use App\Http\Controllers\UserInformationController; use App\Http\Controllers\UserInformationController;
@ -89,6 +91,10 @@ Route::get('/user/edit/verify', [UserEditConfirmController::class, 'verify'])->n
Route::get('/user/withdraw', [UserWithdrawController::class, 'showConfirm'])->name('user.withdraw'); Route::get('/user/withdraw', [UserWithdrawController::class, 'showConfirm'])->name('user.withdraw');
Route::post('/user/withdraw/confirm', [UserWithdrawController::class, 'withdraw'])->name('user.withdraw.confirm'); Route::post('/user/withdraw/confirm', [UserWithdrawController::class, 'withdraw'])->name('user.withdraw.confirm');
// タグ再発行
Route::get('/user/tag_reissue', [UserTagReissueController::class, 'index'])->name('user.tag_reissue');
Route::get('/user/tag_reissue/complete', [UserTagReissueController::class, 'complete'])->name('user.tag_reissue.complete');
// 定期契約情報確認 // 定期契約情報確認
Route::get('regular_contract/info', [RegularContractController::class, 'showInfo'])->name('regular_contract.info'); Route::get('regular_contract/info', [RegularContractController::class, 'showInfo'])->name('regular_contract.info');
@ -97,6 +103,11 @@ Route::get('receipt/input/{contract_id}', [ReceiptController::class, 'input'])->
Route::get('receipt/download/{contract_id}', [ReceiptController::class, 'download'])->name('receipt.download'); Route::get('receipt/download/{contract_id}', [ReceiptController::class, 'download'])->name('receipt.download');
Route::post('receipt/issue/{contract_id}', [ReceiptController::class, 'issue']); Route::post('receipt/issue/{contract_id}', [ReceiptController::class, 'issue']);
// シール再発行
Route::get('/seal/reissue/{contract_id}', [SealReissueController::class, 'index'])->name('seal.reissue');
Route::get('/seal/reissue/reason/{contract_id}', [SealReissueController::class, 'reason'])->name('seal.reissue.reason');
Route::post('/seal/reissue/complete/{contract_id}', [SealReissueController::class, 'complete'])->name('seal.reissue.complete');
// 新規定期契約 // 新規定期契約
Route::get('regular_contract/create', [RegularContractCreateController::class, 'show'])->name('regular_contract.create'); Route::get('regular_contract/create', [RegularContractCreateController::class, 'show'])->name('regular_contract.create');
Route::get('/api/park-detail/{park_id}', [ParkDetailController::class, 'show']); Route::get('/api/park-detail/{park_id}', [ParkDetailController::class, 'show']);