From 1cf94bc8aa73984a74d93adc916ac0eb8e67ef5f Mon Sep 17 00:00:00 2001 From: "kin.rinzen" Date: Wed, 8 Oct 2025 17:55:23 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=9C=E3=82=A4=E3=82=B9?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E7=94=BB=E9=9D=A2=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Admin/InvSettingController.php | 67 +++++++++---- .../Admin/OperatorQueController.php | 7 +- app/Models/InvSetting.php | 9 +- resources/js/app.js | 50 ++++++++++ .../views/admin/invsettings/_form.blade.php | 93 +++++++++++++------ .../views/admin/operator_ques/_form.blade.php | 36 +++++-- .../views/admin/operator_ques/list.blade.php | 5 +- routes/web.php | 1 + 8 files changed, 212 insertions(+), 56 deletions(-) diff --git a/app/Http/Controllers/Admin/InvSettingController.php b/app/Http/Controllers/Admin/InvSettingController.php index 4956823..0422c2d 100644 --- a/app/Http/Controllers/Admin/InvSettingController.php +++ b/app/Http/Controllers/Admin/InvSettingController.php @@ -52,7 +52,7 @@ class InvSettingController extends Controller */ public function save(Request $request) { - // バリデーションルール + // ▼ バリデーションルール $rules = [ 't_number' => 'required|string|max:20', 't_name' => 'required|string|max:50', @@ -66,10 +66,11 @@ class InvSettingController extends Controller 'fax1' => 'nullable|digits_between:2,4', 'fax2' => 'nullable|digits_between:2,4', 'fax3' => 'nullable|digits_between:3,4', - 'company_image' => 'nullable|image|mimes:png,jpg,jpeg|max:2048', + // ← ここは「画像ファイル」ではなく、hiddenに入る「パス」なので image バリデーションは不要 + 'company_image_path' => 'nullable|string|max:255', ]; - // カスタム日本語メッセージ + // ▼ カスタム日本語メッセージ $messages = [ 't_number.required' => '適格請求書発行事業者番号を入力してください。', 't_number.max' => '適格請求書発行事業者番号は20文字以内で入力してください。', @@ -85,8 +86,6 @@ class InvSettingController extends Controller 'adrs.required' => '表示住所を入力してください。', 'adrs.max' => '表示住所は100文字以内で入力してください。', - 'bldg.max' => '建物名は80文字以内で入力してください。', - 'tel1.digits_between' => '電話番号1は2桁から4桁で入力してください。', 'tel2.digits_between' => '電話番号2は2桁から4桁で入力してください。', 'tel3.digits_between' => '電話番号3は3桁から4桁で入力してください。', @@ -94,25 +93,23 @@ class InvSettingController extends Controller 'fax1.digits_between' => 'FAX番号1は2桁から4桁で入力してください。', 'fax2.digits_between' => 'FAX番号2は2桁から4桁で入力してください。', 'fax3.digits_between' => 'FAX番号3は3桁から4桁で入力してください。', - - 'company_image.image' => '社判画像は画像ファイルを選択してください。', - 'company_image.mimes' => '社判画像はpng, jpg, jpeg形式でアップロードしてください。', - 'company_image.max' => '社判画像は2MB以下にしてください。', ]; - // バリデーション実行(カスタムメッセージ適用) + // ▼ バリデーション実行 $request->validate($rules, $messages); - // データ整形 + // ▼ データ整形 $zipcode = $request->zip1 . '-' . $request->zip2; $tel = implode('-', array_filter([$request->tel1, $request->tel2, $request->tel3])); $fax = implode('-', array_filter([$request->fax1, $request->fax2, $request->fax3])); - // 既存レコードを取得(1レコード運用) + // ▼ 既存レコードを取得(1レコード運用) $row = InvSetting::first(); - // 画像処理 - $imagePath = $row?->company_image_path; + // ▼ 画像パスを設定(AJAX アップロード済みファイルのパスを優先) + $imagePath = $request->company_image_path; + + // ▼ フォームで新たにファイルを送信した場合のみ再保存(保険的処理) if ($request->hasFile('company_image')) { if ($imagePath && Storage::disk('public')->exists($imagePath)) { Storage::disk('public')->delete($imagePath); @@ -120,7 +117,7 @@ class InvSettingController extends Controller $imagePath = $request->file('company_image')->store('inv', 'public'); } - // レコードを新規作成 or 更新 + // ▼ レコードを新規作成 or 更新 if ($row) { $row->update([ 't_number' => $request->t_number, @@ -130,7 +127,7 @@ class InvSettingController extends Controller 'bldg' => $request->bldg, 'tel_num' => $tel, 'fax_num' => $fax, - 'company_image_path' => $imagePath, + 'company_image_path' => $imagePath, // ← hiddenの値 or 新規アップロード結果を保存 ]); } else { InvSetting::create([ @@ -148,4 +145,42 @@ class InvSettingController extends Controller return back()->with('success', 'インボイス設定を登録しました。'); } + + /** + * 社判画像アップロード(AJAX用) + */ + public function upload(Request $request) + { + // ファイルがアップロードされているか確認 + if ($request->hasFile('company_image_file')) { + + // 拡張子チェック & バリデーション + $request->validate([ + 'company_image_file' => 'required|image|mimes:png,jpg,jpeg|max:2048', + ], [ + 'company_image_file.image' => '画像ファイルを選択してください。', + 'company_image_file.mimes' => 'アップロード可能な形式は png, jpg, jpeg のみです。', + 'company_image_file.max' => 'ファイルサイズは2MB以下にしてください。', + ]); + + // ファイル保存(public/storage/inv に格納) + $path = $request->file('company_image_file')->store('inv', 'public'); + + // ファイル名を抽出 + $fileName = basename($path); + + // JSONで返却(JSが受け取る) + return response()->json([ + 'file_name' => $fileName, + 'path' => $path, + ]); + } + + // ファイル未選択時 + return response()->json([ + 'error' => 'ファイルが選択されていません。' + ], 400); + } + + } diff --git a/app/Http/Controllers/Admin/OperatorQueController.php b/app/Http/Controllers/Admin/OperatorQueController.php index 81250ff..5f06e2c 100644 --- a/app/Http/Controllers/Admin/OperatorQueController.php +++ b/app/Http/Controllers/Admin/OperatorQueController.php @@ -26,10 +26,11 @@ class OperatorQueController extends Controller $que_status = $request->input('que_status'); // 許可されたカラム名のリスト(DB定義に合わせて) - $allowedSorts = ['que_id', 'ope_id', 'que_status', 'created_at', 'updated_at']; + $allowedSorts = ['que_id', 'ope_id', 'que_status', 'created_at', 'updated_at', 'user_id', 'park_id', 'que_class']; if (!in_array($sort, $allowedSorts)) { $sort = 'que_id'; + } if (!in_array($sort_type, ['asc', 'desc'])) { @@ -75,7 +76,7 @@ class OperatorQueController extends Controller // 登録処理 OperatorQue::create($data); - return redirect()->route('operator_ques')->with('success', 'オペレーターキューを登録しました。'); + return redirect()->route('operator_ques')->with('success', '登録しました。'); } @@ -100,7 +101,7 @@ class OperatorQueController extends Controller $que->fill($data)->save(); - return redirect()->route('operator_ques')->with('success', 'オペレータキューを更新しました。'); + return redirect()->route('operator_ques')->with('success', '更新しました。'); } /** diff --git a/app/Models/InvSetting.php b/app/Models/InvSetting.php index 2c9be1b..767fb14 100644 --- a/app/Models/InvSetting.php +++ b/app/Models/InvSetting.php @@ -11,6 +11,13 @@ class InvSetting extends Model public $timestamps = true; protected $fillable = [ - 't_number', 't_name', 'zipcode', 'adrs', 'bldg', 'tel_num', 'fax_num', 'company_image_path', + + 't_number', // 適格事業者番号 + 't_name', // 事業者名 + 'zipcode', // 郵便番号 + 'adrs', // 住所 + 'tel_num', // 電話番号 + 'fax_num', // FAX番号 + 'company_image_path', // 会社ロゴ画像パス(任意) ]; } diff --git a/resources/js/app.js b/resources/js/app.js index 6037c80..88884b0 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -228,3 +228,53 @@ $('#delete_edit').on('click', function (e) { } }); }); + +$(function () { + // ▼ 「アップロード」ボタンを押すと、ファイル選択ダイアログを開く + $(document).on('click', '.upload-file', function () { + $(this).siblings('input[type=file]').click(); + }); + + // ▼ ファイル選択後、自動でAJAXアップロード処理を行う + $(document).on('change', 'input[name=company_image_file]', function () { + const file = this.files[0]; + if (!file) return; + + const formData = new FormData(); + formData.append('company_image_file', file); + formData.append('_token', $('input[name=_token]').val()); + + $.ajax({ + url: '/inv_setting/upload', // ルート:アップロード先 + type: 'POST', + data: formData, + processData: false, + contentType: false, + success: function (res) { + // 成功時:ファイル名を表示・hidden項目に反映 + $('input[name=company_image_path]').val(res.path); + $('.filename').text(res.file_name); + + // プレビューを更新 + const previewHtml = `
+ 社判画像 +
`; + $('.uploaded-file').after(previewHtml); + + alert('アップロードが完了しました。'); + }, + error: function (xhr) { + alert('アップロードに失敗しました。'); + } + }); + }); + + // ▼ 削除ボタン(✕)をクリックしたらファイル情報をクリア + $(document).on('click', '.delete-file', function () { + $('input[name=company_image_path]').val(''); + $('.filename').text(''); + $('img[alt="社判画像"]').remove(); + }); +}); + diff --git a/resources/views/admin/invsettings/_form.blade.php b/resources/views/admin/invsettings/_form.blade.php index d41cd05..022daf6 100644 --- a/resources/views/admin/invsettings/_form.blade.php +++ b/resources/views/admin/invsettings/_form.blade.php @@ -87,38 +87,79 @@ - {{-- 表示FAX番号 --}} -
- -
- - - - - - - -
-
+ {{-- 表示FAX番号 --}} +
+ +
+ + - + + - + +
+
+ + {{-- ▼ 社判画像アップロード欄 --}} +
+ {{-- 左側ラベル --}} +
+ +
+ + {{-- 右側アップロード欄 --}} +
+
+ + {{-- 非表示のファイル選択ボタン --}} + + + {{-- 表示ボタン(クリックでファイル選択を開く) --}} + + アップロード + + + {{-- アップロード済みファイル表示エリア --}} +
+ {{-- DB保存用の hidden input --}} + + + {{-- ファイル名表示 --}} + + {{ old('company_image_path', basename($row->company_image_path ?? '')) }} + + + {{-- 削除ボタン(画像がある時のみ表示) --}} + @if(!empty($row->company_image_path)) + + + + @endif +
+
+ + {{-- プレビュー画像(存在する場合のみ表示) --}} + @if(!empty($row->company_image_path)) +
+ 社判画像 +
+ @endif +
+
+ {{-- ▲ 社判画像アップロード欄 --}} - {{-- 社判画像 --}} -
- -
- - @if(!empty($row->company_image_path)) - - @endif -
-
{{-- 登録ボタン --}}
- -
+ +
- + @endsection diff --git a/resources/views/admin/operator_ques/_form.blade.php b/resources/views/admin/operator_ques/_form.blade.php index afaad26..0b2575b 100644 --- a/resources/views/admin/operator_ques/_form.blade.php +++ b/resources/views/admin/operator_ques/_form.blade.php @@ -48,20 +48,28 @@ {{-- 利用者名 --}}
- +
- @foreach($users as $item) - @endforeach + + {{-- 編集時でも値を保持するための hidden --}} + @if($isEdit) + + @endif
{{-- 携帯電話番号 --}} @@ -105,21 +113,31 @@ value="{{ old('contract_id', $contract_id ?? '') }}" class="form-control form-control-lg" placeholder="{{ __('validation.attributes.contract_id') }}" - readonly> + @if($isEdit) readonly @endif> + {{-- 駐輪場 --}}
- +
- @foreach($parks as $key => $item) - + @endforeach + + {{-- 編集時でも値を保持するための hidden --}} + @if($isEdit) + + @endif
{{-- キュー種別 --}} diff --git a/resources/views/admin/operator_ques/list.blade.php b/resources/views/admin/operator_ques/list.blade.php index 5191983..3c66644 100644 --- a/resources/views/admin/operator_ques/list.blade.php +++ b/resources/views/admin/operator_ques/list.blade.php @@ -103,9 +103,10 @@ 利用者名 携帯電話番号 自宅電話番号 + 定期契約ID 駐輪場 キュー種別 - キューコメント + キューコメント キューステータス キューステータスコメント 処理リンク @@ -124,11 +125,13 @@ {{ !empty($item->getUser()) ? $item->getUser()->user_name : '' }} {{ !empty($item->getUser()) ? $item->getUser()->user_mobile : '' }} {{ !empty($item->getUser()) ? $item->getUser()->user_homephone : '' }} + {{ $item->contract_id }} {{ !empty($item->getPark()) ? $item->getPark()->park_name : '' }} {{ $item->getQueClassLabel() }} {{ $item->que_comment }} {{ $item->getQueStatusLabel() }} {{ $item->que_status_comment }} + @endforeach diff --git a/routes/web.php b/routes/web.php index 7aa4bb4..59e6508 100644 --- a/routes/web.php +++ b/routes/web.php @@ -482,6 +482,7 @@ Route::middleware('auth')->group(function () { // [東京都|〇〇駐輪場] インボイス設定マスタ Route::match(['get', 'post'], '/inv_settings', [InvSettingController::class, 'form'])->name('inv_settings'); Route::post('/inv_settings/save', [InvSettingController::class, 'save'])->name('inv_settings_save'); + Route::post('/inv_settings/upload', [InvSettingController::class, 'upload'])->name('inv_settings_upload'); // [東京都|〇〇駐輪場] ゾーンマスタ Route::match(['get', 'post'], '/zones', [ZoneController::class, 'list'])->name('zones');