diff --git a/app/Http/Controllers/Admin/UsertypeController.php b/app/Http/Controllers/Admin/UsertypeController.php
index 1ce9a6e..f075eff 100644
--- a/app/Http/Controllers/Admin/UsertypeController.php
+++ b/app/Http/Controllers/Admin/UsertypeController.php
@@ -27,29 +27,48 @@ class UsertypeController extends Controller
if (!in_array($sort, $allowSort, true)) {
$sort = 'user_categoryid';
}
+
$sortType = strtolower($request->input('sort_type', 'asc'));
if (!in_array($sortType, ['asc', 'desc'], true)) {
$sortType = 'asc';
}
+
+ $action = $request->input('action');
+ if ($action === 'unlink') {
+ $request->merge([
+ 'filter_sort_order' => '',
+ 'filter_usertype_subject1' => '',
+ 'filter_usertype_subject2' => '',
+ 'filter_usertype_subject3' => '',
+ 'page' => 1,
+ ]);
+ }
+
$inputs = [
'isMethodPost' => $request->isMethod('post') ? 1 : 0,
- 'isExport' => 0,
- 'sort' => $sort,
- 'sort_type' => $sortType,
- 'page' => (int) $request->get('page', 1),
+ 'isExport' => 0,
+ 'sort' => $sort,
+ 'sort_type' => $sortType,
+ 'page' => (int) $request->get('page', 1),
+ 'action' => $action,
];
+
$filters = [
- 'filter_sort_order' => $request->input('filter_sort_order', ''),
- 'filter_usertype_subject1' => $request->input('filter_usertype_subject1', ''),
- 'filter_usertype_subject2' => $request->input('filter_usertype_subject2', ''),
- 'filter_usertype_subject3' => $request->input('filter_usertype_subject3', ''),
+ 'filter_sort_order' => $request->input('filter_sort_order', ''),
+ 'filter_usertype_subject1'=> $request->input('filter_usertype_subject1', ''),
+ 'filter_usertype_subject2'=> $request->input('filter_usertype_subject2', ''),
+ 'filter_usertype_subject3'=> $request->input('filter_usertype_subject3', ''),
];
+
$searchParams = array_merge($inputs, $filters);
+
$viewData = $searchParams;
$viewData['list'] = Usertype::search($searchParams);
+
if ($viewData['list']->total() > 0 && $viewData['page'] > $viewData['list']->lastPage()) {
return redirect()->route('usertypes');
}
+
return view('admin.usertypes.list', $viewData);
}
@@ -82,17 +101,24 @@ class UsertypeController extends Controller
// バリデーションルール(最小限)
$rules = [
- 'sort_order' => 'nullable|integer',
- 'usertype_subject1' => 'nullable|string|max:255',
- 'usertype_subject2' => 'nullable|string|max:255',
- 'usertype_subject3' => 'nullable|string|max:255',
- 'print_name' => 'required|string|max:255',
- 'usertype_money' => 'nullable|string|max:255',
- 'usertype_remarks' => 'nullable|string|max:255',
+ 'sort_order' => 'required|integer',
+ 'usertype_subject1' => 'required|string|max:10',
+ 'usertype_subject2' => 'required|string|max:10',
+ 'usertype_subject3' => 'nullable|string|max:10',
+ 'print_name' => 'nullable|string|max:20',
+ 'usertype_money' => 'nullable|string|max:10',
+ 'usertype_remarks' => 'nullable|string|max:85',
];
+
+
$messages = [
- 'print_name.required' => '印字名は必須です。',
- 'sort_order.integer' => 'ソートオーダーは数値で入力してください。',
+ 'sort_order.required' => 'ソートオーダーは必須です。',
+ 'sort_order.integer' => 'ソートオーダーは数値で入力してください。',
+
+ 'usertype_subject1.required' => '分類名1は必須です。',
+ 'usertype_subject2.required' => '分類名2は必須です。',
+
+ // 'print_name.required' => '印字名は必須です。',
];
$validator = Validator::make($inputs, $rules, $messages);
@@ -110,7 +136,7 @@ class UsertypeController extends Controller
});
if ($ok) {
- return redirect()->route('usertypes')->with('success', '登録しました。');
+ return redirect()->route('usertypes')->with('success', '登録が完了しました。');
}
return back()->with('error', '登録に失敗しました。')->withInput();
}
@@ -122,65 +148,66 @@ class UsertypeController extends Controller
public function edit(Request $request, $id)
{
- $usertype = Usertype::findOrFail($id);
+ $record = Usertype::findOrFail($id);
+
+ $data = [
+ 'record' => $record,
+ 'isEdit' => true,
+ 'isInfo' => false,
+ ];
- // 画面に渡す初期データ(既存の構成に合わせて attributes を使う)
- $data = $usertype->getAttributes();
if (method_exists($this, 'getDataDropList')) {
- $dataList = $this->getDataDropList();
- $data = array_merge($data, $dataList);
+ $data = array_merge($data, $this->getDataDropList());
}
+ // POST:更新処理
if ($request->isMethod('POST')) {
- $type = false;
- // ▼ 内蔵バリデーション(FormRequest を使わない)
$rules = [
- 'sort_order' => 'nullable|integer',
- 'usertype_subject1' => 'nullable|string|max:255',
- 'usertype_subject2' => 'nullable|string|max:255',
- 'usertype_subject3' => 'nullable|string|max:255',
- 'print_name' => 'required|string|max:255',
- 'usertype_money' => 'nullable|string|max:255',
- 'usertype_remarks' => 'nullable|string|max:255',
+ 'sort_order' => 'required|integer',
+ 'usertype_subject1' => 'required|string|max:10',
+ 'usertype_subject2' => 'required|string|max:10',
+ 'usertype_subject3' => 'nullable|string|max:10',
+ 'print_name' => 'nullable|string|max:20',
+ 'usertype_money' => 'nullable|string|max:10',
+ 'usertype_remarks' => 'nullable|string|max:85',
];
+
+
$messages = [
- 'print_name.required' => '印字名は必須です。',
- 'sort_order.integer' => 'ソートオーダーは数値で入力してください。',
+ 'sort_order.required' => 'ソートオーダーは必須です。',
+ 'sort_order.integer' => 'ソートオーダーは数値で入力してください。',
+
+ 'usertype_subject1.required' => '分類名1は必須です。',
+ 'usertype_subject2.required' => '分類名2は必須です。',
+ 'usertype_subject3.required' => '分類名3は必須です。',
+
];
+
$validator = Validator::make($request->all(), $rules, $messages);
- // 入力値を $data にマージ(既存ロジック踏襲)
- $requestAll = $request->all();
- $data = array_merge($data, $requestAll);
-
if ($validator->fails()) {
return back()->withErrors($validator)->withInput();
}
- \DB::transaction(function () use ($data, &$type, $usertype) {
- // fill するフィールドだけを明示したい場合は only(...) で絞ってもOK
- $usertype->fill([
- 'sort_order' => $data['sort_order'] ?? null,
- 'usertype_subject1' => $data['usertype_subject1'] ?? null,
- 'usertype_subject2' => $data['usertype_subject2'] ?? null,
- 'usertype_subject3' => $data['usertype_subject3'] ?? null,
- 'print_name' => $data['print_name'] ?? null,
- 'usertype_money' => $data['usertype_money'] ?? null,
- 'usertype_remarks' => $data['usertype_remarks'] ?? null,
+ \DB::transaction(function () use ($request, $record) {
+ $record->fill([
+ 'sort_order' => $request->sort_order,
+ 'usertype_subject1' => $request->usertype_subject1,
+ 'usertype_subject2' => $request->usertype_subject2,
+ 'usertype_subject3' => $request->usertype_subject3,
+ 'print_name' => $request->print_name,
+ 'usertype_money' => $request->usertype_money,
+ 'usertype_remarks' => $request->usertype_remarks,
]);
- $usertype->save();
- $type = true;
+ $record->save();
});
- if ($type) {
- return redirect()->route('usertypes')->with('success', '更新しました。');
- }
- return back()->with('error', '更新に失敗しました。')->withInput();
+ return redirect()->route('usertypes')->with('success', '更新が完了しました。');
}
- // GET: 画面表示(既存のビューに合わせて返す)
+ // GET:画面表示
return view('admin.usertypes.edit', $data);
}
@@ -196,7 +223,7 @@ class UsertypeController extends Controller
$arr_pk = [$arr_pk];
}
if (empty($arr_pk)) {
- return redirect()->route('usertypes')->with('error', '削除するユーザーを選択してください。');
+ return redirect()->route('usertypes')->with('error', '削除対象を1件以上選択してください。');
}
if (Usertype::deleteByPk($arr_pk)) {
@@ -219,16 +246,10 @@ class UsertypeController extends Controller
public function export(Request $request)
{
- $timestamp = now()->format('YmdHis');
- $filename = "利用者分類マスタ{$timestamp}.csv";
- $filePath = storage_path("app/{$filename}");
- $headers = [
- 'Content-Type' => 'text/csv; charset=UTF-8',
- 'Content-Encoding' => 'UTF-8',
- 'Pragma' => 'no-cache',
- 'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
- 'Expires' => '0',
- ];
+ // ファイル名
+ $filename = '利用者分類マスタ_' . now()->format('YmdHis') . '.csv';
+
+ // 検索条件(一覧と同じ)
$inputs = [
'isMethodPost' => 0,
'isExport' => 1,
@@ -241,29 +262,34 @@ class UsertypeController extends Controller
];
$dataExport = Usertype::search($inputs);
- $columns = array(
- __('利用者分類ID'),// 0
- __('分類名'),// 1
- __('適用料率'),// 2
- __('備考'),// 3
- );
- $file = fopen($filePath, 'w+');
- fputcsv($file, $columns);
- foreach ($dataExport as $items) {
- fputcsv(
- $file,
- array(
- $items->user_categoryid,
- $items->print_name,
- $items->usertype_money,
- $items->usertype_remarks, // 3
- )
- );
- }
- fclose($file);
- return Response::download($filePath, $filename, $headers)->deleteFileAfterSend(true);
+
+ return response()->streamDownload(function () use ($dataExport) {
+
+ // Excel用 UTF-8 BOM
+ echo "\xEF\xBB\xBF";
+
+ // ヘッダー行
+ echo "利用者分類ID,ソートオーダー,分類名1,分類名2,分類名3,適用料率,備考\n";
+
+ // データ行
+ foreach ($dataExport as $item) {
+ echo implode(',', [
+ $item->user_categoryid,
+ $item->sort_order,
+ $item->usertype_subject1,
+ $item->usertype_subject2,
+ $item->usertype_subject3,
+ $item->usertype_money,
+ $item->usertype_remarks,
+ ]) . "\n";
+ }
+
+ }, $filename, [
+ 'Content-Type' => 'text/csv; charset=UTF-8',
+ ]);
}
+
public function import(Request $request)
{
$file = $request->file('file');
diff --git a/app/Utils.php b/app/Utils.php
index a576cd5..aa251f4 100644
--- a/app/Utils.php
+++ b/app/Utils.php
@@ -20,8 +20,7 @@ use Illuminate\Support\Facades\Hash;
class Utils
{
// ページあたりのアイテム数(旧システムから継承)
- // const item_per_page = 50;
- const item_per_page = 20;
+ const item_per_page = 50;
// 画像保存パス(旧システムから継承)
const image_path = 'storage/images/';
diff --git a/public/js/app.js b/public/js/app.js
index d4a7d41..1453a76 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -142,34 +142,72 @@ $('#import_csv').on('click', function () {
}
});
});
+/** * CSV出力確認ダイアログ 以前のバージョン */
+
+// $('#export_csv').on('click', function () {
+// var _action = $(this).attr('action'),
+// user_id = $('#user_id').length ? $('#user_id').val() : '',
+// member_id = $('#member_id').length ? $('#member_id').val() : '',
+// user_tag_serial = $('#user_tag_serial').length ? $('#user_tag_serial').val() : '',
+// user_phonetic = $('#user_phonetic').length ? $('#user_phonetic').val() : '',
+// phone = $('#phone').length ? $('#phone').val() : '',
+// crime = $('#crime').length ? $('#crime').val() : '',
+// sort = $('#sort').length ? $('#sort').val() : '',
+// sort_type = $('#sort_type').length ? $('#sort_type').val() : '';
+
+// $.confirm({
+// title: '確認ダイアログ。',
+// content: '!CSVファイルを出力します。よろしいですか?はい/いいえ',
+// buttons: {
+// ok: {
+// text: "はい",
+// btnClass: 'btn-primary',
+// keys: ['enter'],
+// action: function action() {
+// window.location.href = _action + '?user_id=' + user_id + '&member_id=' + member_id + '&user_tag_serial=' + user_tag_serial + '&user_phonetic=' + user_phonetic + '&phone=' + phone + '&crime=' + crime + '&sort=' + sort + '&sort_type=' + sort_type + '&isExport=1';
+// }
+// },
+// いいえ: function _() {}
+// }
+// });
+// });
+
+$(document).on('click', '#export_csv, [data-export-csv="1"]', function () {
+ var action = $(this).attr('action') || $(this).data('action');
+ var formSelector = $(this).data('form') || '#list-form';
+
+ if (!action) return;
+
+
+ var query = '';
+ if (formSelector && $(formSelector).length) {
+ query = $(formSelector).serialize();
+ query = query
+ .split('&')
+ .filter(function (p) { return p && p.indexOf('_token=') !== 0; })
+ .join('&');
+ }
-$('#export_csv').on('click', function () {
- var _action = $(this).attr('action'),
- user_id = $('#user_id').val(),
- member_id = $('#member_id').val(),
- user_tag_serial = $('#user_tag_serial').val(),
- user_phonetic = $('#user_phonetic').val(),
- phone = $('#phone').val(),
- crime = $('#crime').val(),
- sort = $('#sort').val(),
- sort_type = $('#sort_type').val();
$.confirm({
title: '確認ダイアログ。',
- content: '!CSVファイルを出力します。よろしいですか?はい/いいえ',
+ content: 'CSVファイルを出力します。よろしいですか?はい/いいえ',
buttons: {
ok: {
- text: "はい",
+ text: 'はい',
btnClass: 'btn-primary',
keys: ['enter'],
- action: function action() {
- window.location.href = _action + '?user_id=' + user_id + '&member_id=' + member_id + '&user_tag_serial=' + user_tag_serial + '&user_phonetic=' + user_phonetic + '&phone=' + phone + '&crime=' + crime + '&sort=' + sort + '&sort_type=' + sort_type + '&isExport=1';
+ action: function () {
+ var url = action + (query ? ('?' + query + '&isExport=1') : '?isExport=1');
+ window.location.href = url;
}
},
- いいえ: function _() {}
+ いいえ: function () {}
}
});
});
+
+
// for sorting
$('.table thead th.sorting').on('click', function (e) {
var sort = $(this).attr('sort');
@@ -1612,6 +1650,23 @@ $('#delete_edit').on('click', function (e) {
});
});
+// 共通 戻るボタン
+$(document).on('click', '#btn_back', function (e) {
+ e.preventDefault();
+
+ // data-back-url があれば優先
+ var backUrl = $(this).data('back-url');
+ if (backUrl) {
+ window.location.href = backUrl;
+ return;
+ }
+
+ // fallback:直前の画面
+ window.history.back();
+});
+
+
+
$(function () {
// ▼ 「アップロード」ボタンを押すと、ファイル選択ダイアログを開く
$(document).on('click', '.upload-file', function () {
diff --git a/resources/views/admin/regularcontracts/list.blade.php b/resources/views/admin/regularcontracts/list.blade.php
index fc45c92..5c70b1b 100644
--- a/resources/views/admin/regularcontracts/list.blade.php
+++ b/resources/views/admin/regularcontracts/list.blade.php
@@ -2,533 +2,666 @@
@section('title', '定期契約マスタ')
@section('content')
-
-
-
-