This commit is contained in:
parent
098428c67c
commit
aac63f7d0a
@ -107,7 +107,7 @@
|
|||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<div class="col-md-12 font-weight-bold mb-1">タグ発送ステータス変更</div>
|
<div class="col-md-12 font-weight-bold mb-1">タグ発送ステータス変更</div>
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{{-- form 不包含表格 --}}
|
{{-- form はテーブル外に置く(hidden だけ持つ) --}}
|
||||||
<form id="statusForm" method="POST" action="{{ route('tagissue.status') }}">
|
<form id="statusForm" method="POST" action="{{ route('tagissue.status') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<input type="hidden" name="action" id="statusAction" value="">
|
<input type="hidden" name="action" id="statusAction" value="">
|
||||||
@ -138,12 +138,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="overflow-x: auto;">
|
<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">
|
<thead class="thead-light">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:40px;">
|
<th style="width:40px;">
|
||||||
<input type="checkbox"
|
<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>
|
||||||
<th sort="que_id">キューID</th>
|
<th sort="que_id">キューID</th>
|
||||||
<th sort="user_tag_serial">タグシリアル</th>
|
<th sort="user_tag_serial">タグシリアル</th>
|
||||||
@ -166,12 +167,14 @@
|
|||||||
@foreach($users as $user)
|
@foreach($users as $user)
|
||||||
<tr>
|
<tr>
|
||||||
<td style="background-color:#faebd7;">
|
<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>
|
</td>
|
||||||
@php
|
{{-- ★ 逐行のDB取得は不要。JOIN結果をそのまま使う --}}
|
||||||
$que = \App\Models\OperatorQue::where('user_id', $user->user_id)->first();
|
<td>{{ $user->que_id }}</td>
|
||||||
@endphp
|
|
||||||
<td>{{ $que ? $que->que_id : '' }}</td>
|
|
||||||
<td>{{ $user->user_tag_serial }}</td>
|
<td>{{ $user->user_tag_serial }}</td>
|
||||||
<td>{{ $user->user_tag_serial_64 }}</td>
|
<td>{{ $user->user_tag_serial_64 }}</td>
|
||||||
<td>{{ $user->user_tag_issue }}</td>
|
<td>{{ $user->user_tag_issue }}</td>
|
||||||
@ -205,15 +208,38 @@
|
|||||||
{{-- 印刷処理用 JS --}}
|
{{-- 印刷処理用 JS --}}
|
||||||
<script>
|
<script>
|
||||||
// タグ発送宛名印刷
|
// タグ発送宛名印刷
|
||||||
|
// 仕様:
|
||||||
|
// ① 一覧内に「タグ未発送(que_status=1)」が存在するか確認
|
||||||
|
// ② 存在しなければ「発送対象がありません。」
|
||||||
|
// ③ 存在するが未選択なら「1件以上選択してください。」
|
||||||
|
// ④ それ以外は確認ダイアログ→送信
|
||||||
function handlePrintLabels() {
|
function handlePrintLabels() {
|
||||||
var checkboxes = document.querySelectorAll('input[name="ids[]"]:checked');
|
var table = document.getElementById('user-table');
|
||||||
if (checkboxes.length === 0) {
|
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({
|
$.alert({
|
||||||
title: '選択エラー',
|
title: '選択エラー',
|
||||||
content: '1件以上選択してください。'
|
content: '1件以上選択してください。'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.confirm({
|
$.confirm({
|
||||||
title: '確認',
|
title: '確認',
|
||||||
content: 'タグ発送用宛名を印刷してよろしいですか?',
|
content: 'タグ発送用宛名を印刷してよろしいですか?',
|
||||||
@ -225,18 +251,21 @@
|
|||||||
form.method = 'POST';
|
form.method = 'POST';
|
||||||
form.action = '/tagissue/print-unissued-labels';
|
form.action = '/tagissue/print-unissued-labels';
|
||||||
form.target = '_blank';
|
form.target = '_blank';
|
||||||
|
|
||||||
var csrf = document.createElement('input');
|
var csrf = document.createElement('input');
|
||||||
csrf.type = 'hidden';
|
csrf.type = 'hidden';
|
||||||
csrf.name = '_token';
|
csrf.name = '_token';
|
||||||
csrf.value = '{{ csrf_token() }}';
|
csrf.value = '{{ csrf_token() }}';
|
||||||
form.appendChild(csrf);
|
form.appendChild(csrf);
|
||||||
checkboxes.forEach(function (cb) {
|
|
||||||
|
checkedCbs.forEach(function (cb) {
|
||||||
var input = document.createElement('input');
|
var input = document.createElement('input');
|
||||||
input.type = 'hidden';
|
input.type = 'hidden';
|
||||||
input.name = 'ids[]';
|
input.name = 'ids[]';
|
||||||
input.value = cb.value;
|
input.value = cb.value;
|
||||||
form.appendChild(input);
|
form.appendChild(input);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.appendChild(form);
|
document.body.appendChild(form);
|
||||||
form.submit();
|
form.submit();
|
||||||
document.body.removeChild(form);
|
document.body.removeChild(form);
|
||||||
@ -247,99 +276,97 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ステータス変更処理
|
// ステータス変更処理
|
||||||
function handleStatusChange(actionType) {
|
function handleStatusChange(actionType) {
|
||||||
var checkboxes = document.querySelectorAll('input[name="ids[]"]:checked');
|
var checkboxes = document.querySelectorAll('input[name="ids[]"]:checked');
|
||||||
if (checkboxes.length === 0) {
|
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({
|
$.alert({
|
||||||
title: '選択エラー',
|
title: '確認エラー',
|
||||||
content: '1件以上選択してください。'
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ids = Array.from(checkboxes).map(cb => cb.value);
|
var confirmMsg = (ajaxType === 'issued')
|
||||||
var ajaxType = (actionType === 'to_issued') ? 'issued' : 'unissued';
|
? 'ステータスをタグ発送済に変更してよろしいですか?'
|
||||||
|
: 'ステータスをタグ未発送に変更してよろしいですか?';
|
||||||
|
|
||||||
fetch('/tagissue/check-status', {
|
$.confirm({
|
||||||
method: 'POST',
|
title: '確認ダイアログ',
|
||||||
headers: {
|
content: confirmMsg,
|
||||||
'Content-Type': 'application/json',
|
buttons: {
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
はい: {
|
||||||
},
|
text: 'はい',
|
||||||
body: JSON.stringify({ ids: ids, type: ajaxType })
|
btnClass: 'btn-primary',
|
||||||
})
|
keys: ['enter'],
|
||||||
.then(response => response.json())
|
action: function () {
|
||||||
.then(data => {
|
var form = document.getElementById('statusForm');
|
||||||
if (ajaxType === 'issued' && data.alreadyIssued.length > 0) {
|
form.querySelectorAll('input[name="ids[]"]').forEach(e => e.remove());
|
||||||
$.alert({
|
ids.forEach(id => {
|
||||||
title: '確認エラー',
|
var input = document.createElement('input');
|
||||||
content: '以下のユーザーはすでにタグ発送済みです:<br>' + data.alreadyIssued.join('<br>')
|
input.type = 'hidden';
|
||||||
});
|
input.name = 'ids[]';
|
||||||
return;
|
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: 'ステータス確認に失敗しました。'
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
})
|
||||||
|
.catch(() => {
|
||||||
// ソート挙動
|
$.alert({
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
title: '通信エラー',
|
||||||
document.querySelectorAll('th[sort]').forEach(function (th) {
|
content: 'ステータス確認に失敗しました。'
|
||||||
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>
|
}
|
||||||
|
|
||||||
|
// ソート挙動
|
||||||
|
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
|
@endsection
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user