This commit is contained in:
parent
9a6abe680f
commit
1cf94bc8aa
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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', '更新しました。');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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', // 会社ロゴ画像パス(任意)
|
||||
];
|
||||
}
|
||||
|
||||
@ -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 = `<div class="mt-2">
|
||||
<img src="/storage/${res.path}" alt="社判画像"
|
||||
style="max-height:100px; border:1px solid #ccc; padding:3px;">
|
||||
</div>`;
|
||||
$('.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();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -87,38 +87,79 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 表示FAX番号 --}}
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">表示FAX番号</label>
|
||||
<div class="col-sm-9 d-flex">
|
||||
<input name="fax1" class="form-control" style="max-width:100px;" value="{{ old('fax1', $fax1) }}">
|
||||
<span class="mx-2">-</span>
|
||||
<input name="fax2" class="form-control" style="max-width:100px;" value="{{ old('fax2', $fax2) }}">
|
||||
<span class="mx-2">-</span>
|
||||
<input name="fax3" class="form-control" style="max-width:100px;" value="{{ old('fax3', $fax3) }}">
|
||||
</div>
|
||||
</div>
|
||||
{{-- 表示FAX番号 --}}
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">表示FAX番号</label>
|
||||
<div class="col-sm-9 d-flex">
|
||||
<input name="fax1" class="form-control" style="max-width:100px;" value="{{ old('fax1', $fax1) }}">
|
||||
<span class="mx-2">-</span>
|
||||
<input name="fax2" class="form-control" style="max-width:100px;" value="{{ old('fax2', $fax2) }}">
|
||||
<span class="mx-2">-</span>
|
||||
<input name="fax3" class="form-control" style="max-width:100px;" value="{{ old('fax3', $fax3) }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ▼ 社判画像アップロード欄 --}}
|
||||
<div class="row">
|
||||
{{-- 左側ラベル --}}
|
||||
<div class="form-group col-3">
|
||||
<label>社判画像</label>
|
||||
</div>
|
||||
|
||||
{{-- 右側アップロード欄 --}}
|
||||
<div class="form-group col-9">
|
||||
<div class="input-group align-items-center">
|
||||
|
||||
{{-- 非表示のファイル選択ボタン --}}
|
||||
<input type="file" class="d-none" name="company_image_file" accept=".jpg,.png,.gif" />
|
||||
|
||||
{{-- 表示ボタン(クリックでファイル選択を開く) --}}
|
||||
<a href="javascript:void(0)" class="btn btn-default upload-file">
|
||||
アップロード
|
||||
</a>
|
||||
|
||||
{{-- アップロード済みファイル表示エリア --}}
|
||||
<div class="uploaded-file pl-2">
|
||||
{{-- DB保存用の hidden input --}}
|
||||
<input type="hidden" name="company_image_path"
|
||||
value="{{ old('company_image_path', $row->company_image_path ?? '') }}">
|
||||
|
||||
{{-- ファイル名表示 --}}
|
||||
<span class="filename">
|
||||
{{ old('company_image_path', basename($row->company_image_path ?? '')) }}
|
||||
</span>
|
||||
|
||||
{{-- 削除ボタン(画像がある時のみ表示) --}}
|
||||
@if(!empty($row->company_image_path))
|
||||
<a href="javascript:void(0)" class="text-dark delete-file ml-1">
|
||||
<i class="fa fa-times" aria-hidden="true"></i>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- プレビュー画像(存在する場合のみ表示) --}}
|
||||
@if(!empty($row->company_image_path))
|
||||
<div class="mt-2">
|
||||
<img src="{{ asset('storage/'.$row->company_image_path) }}"
|
||||
alt="社判画像"
|
||||
style="max-height:100px; border:1px solid #ccc; padding:3px;">
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
{{-- ▲ 社判画像アップロード欄 --}}
|
||||
|
||||
{{-- 社判画像 --}}
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">社判画像</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="file" name="company_image" class="form-control-file">
|
||||
@if(!empty($row->company_image_path))
|
||||
<div class="mt-2">
|
||||
<a href="{{ asset('storage/'.$row->company_image_path) }}" target="_blank">現在の画像を表示</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 登録ボタン --}}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-3">
|
||||
<button type="submit" class="btn btn-success px-3">登録</button>
|
||||
</div>
|
||||
<button type="button" id="register" class="btn btn-lg btn-success mr-2 register">
|
||||
{{ __('登録') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
@ -48,20 +48,28 @@
|
||||
|
||||
{{-- 利用者名 --}}
|
||||
<div class="form-group col-3">
|
||||
<label>{{ __('validation.attributes.user_name') }}</label>
|
||||
<label class="required">{{ __('validation.attributes.user_name') }}</label>
|
||||
</div>
|
||||
<div class="form-group col-9">
|
||||
<select class="form-control form-control-lg" id="select_user" name="user_id">
|
||||
<select class="form-control form-control-lg"
|
||||
id="select_user"
|
||||
name="user_id"
|
||||
@if($isEdit) disabled @endif>
|
||||
<option value="">{{ __('validation.attributes.user_name') }}</option>
|
||||
@foreach($users as $item)
|
||||
<option value="{{ $item->user_seq }}"
|
||||
mobile="{{ $item->user_mobile }}"
|
||||
homePhone="{{ $item->user_homephone }}"
|
||||
<option value="{{ $item->user_seq }}"
|
||||
mobile="{{ $item->user_mobile }}"
|
||||
homePhone="{{ $item->user_homephone }}"
|
||||
@if($item->user_seq == $user_id) selected @endif>
|
||||
{{ $item->user_name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
{{-- 編集時でも値を保持するための hidden --}}
|
||||
@if($isEdit)
|
||||
<input type="hidden" name="user_id" value="{{ $user_id }}">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- 携帯電話番号 --}}
|
||||
@ -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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{-- 駐輪場 --}}
|
||||
<div class="form-group col-3">
|
||||
<label>{{ __('validation.attributes.park_name') }}</label>
|
||||
<label class="required">{{ __('validation.attributes.park_name') }}</label>
|
||||
</div>
|
||||
<div class="form-group col-9">
|
||||
<select class="form-control form-control-lg" name="park_id">
|
||||
<select class="form-control form-control-lg"
|
||||
name="park_id"
|
||||
@if($isEdit) disabled @endif>
|
||||
<option value="">{{ __('validation.attributes.park_name') }}</option>
|
||||
@foreach($parks as $key => $item)
|
||||
<option value="{{ $key }}" @if($key == $park_id) selected @endif>{{ $item }}</option>
|
||||
<option value="{{ $key }}" @if($key == $park_id) selected @endif>
|
||||
{{ $item }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
{{-- 編集時でも値を保持するための hidden --}}
|
||||
@if($isEdit)
|
||||
<input type="hidden" name="park_id" value="{{ $park_id }}">
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- キュー種別 --}}
|
||||
|
||||
@ -103,9 +103,10 @@
|
||||
<th class="sorting {{ ($sort=='user_id') ? ($sort_type=='asc'?'sorting_asc':'sorting_desc') : '' }}" sort="user_id"><span>利用者名</span></th>
|
||||
<th><span>携帯電話番号</span></th>
|
||||
<th><span>自宅電話番号</span></th>
|
||||
<th><span>定期契約ID</span></th>
|
||||
<th class="sorting {{ ($sort=='park_name') ? ($sort_type=='asc'?'sorting_asc':'sorting_desc') : '' }}" sort="park_name"><span>駐輪場</span></th>
|
||||
<th class="sorting {{ ($sort=='que_class') ? ($sort_type=='asc'?'sorting_asc':'sorting_desc') : '' }}" sort="que_class"><span>キュー種別</span></th>
|
||||
<th class="sorting {{ ($sort=='que_comment') ? ($sort_type=='asc'?'sorting_asc':'sorting_desc') : '' }}" sort="que_comment"><span>キューコメント</span></th>
|
||||
<th><span>キューコメント</span></th>
|
||||
<th class="sorting {{ ($sort=='que_status') ? ($sort_type=='asc'?'sorting_asc':'sorting_desc') : '' }}" sort="que_status"><span>キューステータス</span></th>
|
||||
<th><span>キューステータスコメント</span></th>
|
||||
<th><span>処理リンク</span></th>
|
||||
@ -124,11 +125,13 @@
|
||||
<td class="sm-item text-left align-middle">{{ !empty($item->getUser()) ? $item->getUser()->user_name : '' }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ !empty($item->getUser()) ? $item->getUser()->user_mobile : '' }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ !empty($item->getUser()) ? $item->getUser()->user_homephone : '' }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ $item->contract_id }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ !empty($item->getPark()) ? $item->getPark()->park_name : '' }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ $item->getQueClassLabel() }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ $item->que_comment }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ $item->getQueStatusLabel() }}</td>
|
||||
<td class="sm-item text-left align-middle">{{ $item->que_status_comment }}</td>
|
||||
|
||||
<td class="sm-item text-left align-middle"></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
@ -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');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user