【タグ発行キュー処理、履歴表示】提示メッセージ修正
All checks were successful
Deploy main / deploy (push) Successful in 22s

This commit is contained in:
你的名字 2025-10-16 13:34:25 +09:00
parent 098428c67c
commit aac63f7d0a

View File

@ -107,7 +107,7 @@
<div class="row mb-2">
<div class="col-md-12 font-weight-bold mb-1">タグ発送ステータス変更</div>
<div class="col-md-12">
{{-- form 不包含表格 --}}
{{-- form はテーブル外に置くhidden だけ持つ) --}}
<form id="statusForm" method="POST" action="{{ route('tagissue.status') }}">
@csrf
<input type="hidden" name="action" id="statusAction" value="">
@ -138,12 +138,13 @@
</div>
<div style="overflow-x: auto;">
<table class="table table-bordered dataTable text-nowrap">
{{-- テーブルにIDを付与JSセレクタのスコープを限定 --}}
<table id="user-table" class="table table-bordered dataTable text-nowrap">
<thead class="thead-light">
<tr>
<th style="width:40px;">
<input type="checkbox"
onclick="document.querySelectorAll('input[name=\'ids[]\']').forEach(cb => cb.checked = this.checked);">
onclick="document.querySelectorAll('#user-table input[name=\'ids[]\'][type=\'checkbox\']').forEach(cb => cb.checked = this.checked);">
</th>
<th sort="que_id">キューID</th>
<th sort="user_tag_serial">タグシリアル</th>
@ -166,12 +167,14 @@
@foreach($users as $user)
<tr>
<td style="background-color:#faebd7;">
<input type="checkbox" name="ids[]" value="{{ $user->user_id }}">
{{-- data-que-status をJOIN結果から出力未発送=1, 発送済=3 など) --}}
<input type="checkbox"
name="ids[]"
value="{{ $user->user_id }}"
data-que-status="{{ $user->que_status ?? '' }}">
</td>
@php
$que = \App\Models\OperatorQue::where('user_id', $user->user_id)->first();
@endphp
<td>{{ $que ? $que->que_id : '' }}</td>
{{-- 逐行のDB取得は不要。JOIN結果をそのまま使う --}}
<td>{{ $user->que_id }}</td>
<td>{{ $user->user_tag_serial }}</td>
<td>{{ $user->user_tag_serial_64 }}</td>
<td>{{ $user->user_tag_issue }}</td>
@ -205,15 +208,38 @@
{{-- 印刷処理用 JS --}}
<script>
// タグ発送宛名印刷
// 仕様:
// ① 一覧内に「タグ未発送que_status=1」が存在するか確認
// ② 存在しなければ「発送対象がありません。」
// ③ 存在するが未選択なら「1件以上選択してください。」
// ④ それ以外は確認ダイアログ→送信
function handlePrintLabels() {
var checkboxes = document.querySelectorAll('input[name="ids[]"]:checked');
if (checkboxes.length === 0) {
var table = document.getElementById('user-table');
var allCbs = table.querySelectorAll('input[name="ids[]"][type="checkbox"]');
var checkedCbs = table.querySelectorAll('input[name="ids[]"][type="checkbox"]:checked');
// 一覧内に未発送(que_status=1)が1件でもあるか
var hasUnissued = Array.from(allCbs).some(function (cb) {
var v = cb.dataset && cb.dataset.queStatus;
return v != null && String(v).trim() === '1';
});
if (!hasUnissued) {
$.alert({
title: '選択エラー',
content: '発送対象がありません。'
});
return;
}
if (checkedCbs.length === 0) {
$.alert({
title: '選択エラー',
content: '1件以上選択してください。'
});
return;
}
$.confirm({
title: '確認',
content: 'タグ発送用宛名を印刷してよろしいですか?',
@ -225,18 +251,21 @@
form.method = 'POST';
form.action = '/tagissue/print-unissued-labels';
form.target = '_blank';
var csrf = document.createElement('input');
csrf.type = 'hidden';
csrf.name = '_token';
csrf.value = '{{ csrf_token() }}';
form.appendChild(csrf);
checkboxes.forEach(function (cb) {
checkedCbs.forEach(function (cb) {
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'ids[]';
input.value = cb.value;
form.appendChild(input);
});
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
@ -247,99 +276,97 @@
});
}
// ステータス変更処理
function handleStatusChange(actionType) {
var checkboxes = document.querySelectorAll('input[name="ids[]"]:checked');
if (checkboxes.length === 0) {
// ステータス変更処理
function handleStatusChange(actionType) {
var checkboxes = document.querySelectorAll('input[name="ids[]"]:checked');
if (checkboxes.length === 0) {
$.alert({
title: '選択エラー',
content: '1件以上選択してください。'
});
return;
}
var ids = Array.from(checkboxes).map(cb => cb.value);
var ajaxType = (actionType === 'to_issued') ? 'issued' : 'unissued';
fetch('/tagissue/check-status', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
body: JSON.stringify({ ids: ids, type: ajaxType })
})
.then(response => response.json())
.then(data => {
if (ajaxType === 'issued' && data.alreadyIssued.length > 0) {
$.alert({
title: '選択エラー',
content: '1件以上選択してください。'
title: '確認エラー',
content: '以下のユーザーはすでにタグ発送済みです:<br>' + data.alreadyIssued.join('<br>')
});
return;
}
if (ajaxType === 'unissued' && data.alreadyUnissued && data.alreadyUnissued.length > 0) {
$.alert({
title: '確認エラー',
content: '以下のユーザーはすでにタグ未発送です:<br>' + data.alreadyUnissued.join('<br>')
});
return;
}
var ids = Array.from(checkboxes).map(cb => cb.value);
var ajaxType = (actionType === 'to_issued') ? 'issued' : 'unissued';
var confirmMsg = (ajaxType === 'issued')
? 'ステータスをタグ発送済に変更してよろしいですか?'
: 'ステータスをタグ未発送に変更してよろしいですか?';
fetch('/tagissue/check-status', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
body: JSON.stringify({ ids: ids, type: ajaxType })
})
.then(response => response.json())
.then(data => {
if (ajaxType === 'issued' && data.alreadyIssued.length > 0) {
$.alert({
title: '確認エラー',
content: '以下のユーザーはすでにタグ発送済みです:<br>' + data.alreadyIssued.join('<br>')
});
return;
$.confirm({
title: '確認ダイアログ',
content: confirmMsg,
buttons: {
はい: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: function () {
var form = document.getElementById('statusForm');
form.querySelectorAll('input[name="ids[]"]').forEach(e => e.remove());
ids.forEach(id => {
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'ids[]';
input.value = id;
form.appendChild(input);
});
document.getElementById('statusAction').value = actionType;
form.submit();
}
},
いいえ: function () { }
}
if (ajaxType === 'unissued' && data.alreadyUnissued && data.alreadyUnissued.length > 0) {
$.alert({
title: '確認エラー',
content: '以下のユーザーはすでにタグ未発送です:<br>' + data.alreadyUnissued.join('<br>')
});
return;
}
var confirmMsg = (ajaxType === 'issued')
? 'ステータスをタグ発送済に変更してよろしいですか?'
: 'ステータスをタグ未発送に変更してよろしいですか?';
$.confirm({
title: '確認ダイアログ',
content: confirmMsg,
buttons: {
はい: {
text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
action: function () {
var form = document.getElementById('statusForm');
// 古い input 清除
form.querySelectorAll('input[name="ids[]"]').forEach(e => e.remove());
// 动态附加选中 ID
ids.forEach(id => {
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'ids[]';
input.value = id;
form.appendChild(input);
});
document.getElementById('statusAction').value = actionType;
form.submit();
}
},
いいえ: function () { }
}
});
})
.catch(() => {
$.alert({
title: '通信エラー',
content: 'ステータス確認に失敗しました。'
});
});
}
// ソート挙動
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('th[sort]').forEach(function (th) {
th.addEventListener('click', function () {
var sort = th.getAttribute('sort');
var params = new URLSearchParams(window.location.search);
var currentSort = params.get('sort');
var currentType = params.get('sort_type');
var nextType = (currentSort === sort && currentType === 'asc') ? 'desc' : 'asc';
params.set('sort', sort);
params.set('sort_type', nextType);
window.location.search = params.toString();
});
})
.catch(() => {
$.alert({
title: '通信エラー',
content: 'ステータス確認に失敗しました。'
});
});
</script>
}
// ソート挙動
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('th[sort]').forEach(function (th) {
th.addEventListener('click', function () {
var sort = th.getAttribute('sort');
var params = new URLSearchParams(window.location.search);
var currentSort = params.get('sort');
var currentType = params.get('sort_type');
var nextType = (currentSort === sort && currentType === 'asc') ? 'desc' : 'asc';
params.set('sort', sort);
params.set('sort_type', nextType);
window.location.search = params.toString();
});
});
});
</script>
@endsection