krgm.so-manager-dev.com/app/Http/Controllers/Admin/UsersController.php
ou.zaikou e1629913bd 初回コミット
Signed-off-by:  ou.zaikou<caihaoweng@gmail.com>
2025-08-21 23:09:40 +09:00

319 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Symfony\Component\HttpFoundation\StreamedResponse;
class UsersController
{
/**
* 利用者一覧
* - テーブル名: user
* - 主キー: user_seqAUTO_INCREMENT:contentReference[oaicite:3]{index=3}
* - よく使う表示項目のみ選択(必要に応じて拡張)
*/
// 先确保use App\Http\Controllers\Controller; を追加し、必要なら extends Controller にする
// use Symfony\Component\HttpFoundation\StreamedResponse; は既にOK
/**
* 一覧(絞り込み + ページング)
*/
public function list(Request $request)
{
// ▼ 並び順(ホワイトリスト)
$sortable = [
'user_seq',
'user_id',
'member_id',
'contract_number',
'user_tag_serial',
'user_tag_serial_64',
'qr_code',
'tag_qr_flag',
'user_aid',
'user_place_qrid',
'user_categoryid',
'user_name',
'user_birthdate',
'user_age',
'user_homephone',
'user_primemail',
'user_submail',
'user_school',
];
$sort = $request->input('sort', 'user_seq');
$sortType = strtolower($request->input('sort_type', 'desc')) === 'asc' ? 'asc' : 'desc';
if (!in_array($sort, $sortable, true)) {
$sort = 'user_seq';
}
// ▼ 絞り込み値('' のときだけ無視。'0' は有効値として扱う)
$user_id = trim((string) $request->input('user_id', ''));
$member_id = trim((string) $request->input('member_id', ''));
$user_tag_serial = trim((string) $request->input('user_tag_serial', ''));
$user_phonetic = trim((string) $request->input('user_phonetic', ''));
$phone = trim((string) $request->input('phone', '')); // 携帯/自宅の両方対象
$crime = trim((string) $request->input('crime', '')); // 防犯登録番号(暫定: qr_code
$user_categoryid = (string) $request->input('user_categoryid', '');
$tag_qr_flag = (string) $request->input('tag_qr_flag', ''); // 0=タグ / 1=QR
$quit_flag = (string) $request->input('quit_flag', ''); // 0=いいえ / 1=はい
$quit_from = (string) $request->input('quit_from', ''); // YYYY-MM-DD
$quit_to = (string) $request->input('quit_to', ''); // YYYY-MM-DD
// ▼ ベースクエリ(一覧で使う列が多いので一旦 * を許容)
$query = DB::table('user')->select('user.*');
// ▼ テキスト系
if ($user_id !== '')
$query->where('user.user_id', 'like', "%{$user_id}%");
if ($member_id !== '')
$query->where('user.member_id', 'like', "%{$member_id}%");
if ($user_tag_serial !== '')
$query->where('user.user_tag_serial', 'like', "%{$user_tag_serial}%");
if ($user_phonetic !== '')
$query->where('user.user_phonetic', 'like', "%{$user_phonetic}%");
if ($phone !== '') {
$query->where(function ($w) use ($phone) {
$w->where('user.user_mobile', 'like', "%{$phone}%")
->orWhere('user.user_homephone', 'like', "%{$phone}%");
});
}
if ($crime !== '') {
// ※ dump に防犯登録番号の明確なカラムが無いため暫定的に qr_code を対象
$query->where('user.qr_code', 'like', "%{$crime}%");
}
// ▼ セレクト/ラジオ('' 以外なら適用。'0' も通す)
if ($user_categoryid !== '')
$query->where('user.user_categoryid', $user_categoryid);
if ($tag_qr_flag !== '')
$query->where('user.tag_qr_flag', (int) $tag_qr_flag);
if ($quit_flag !== '')
$query->where('user.user_quit_flag', (int) $quit_flag);
// ▼ 日付範囲(退会日)
if ($quit_from !== '')
$query->where('user.user_quitday', '>=', $quit_from);
if ($quit_to !== '')
$query->where('user.user_quitday', '<=', $quit_to);
// ▼ 並び & ページング
$list = $query->orderBy("user.{$sort}", $sortType)->paginate(20);
// ▼ 画面に渡す(フォーム再描画用に絞り込み値も)
return view('admin.users.list', [
'list' => $list,
'sort' => $sort,
'sort_type' => $sortType,
'user_id' => $user_id,
'member_id' => $member_id,
'user_tag_serial' => $user_tag_serial,
'user_phonetic' => $user_phonetic,
'phone' => $phone,
'crime' => $crime,
'user_categoryid' => $user_categoryid,
'tag_qr_flag' => $tag_qr_flag,
'quit_flag' => $quit_flag,
'quit_from' => $quit_from,
'quit_to' => $quit_to,
]);
}
/**
* CSV 出力(一覧と同じ絞り込みを適用)
*/
public function export(Request $request): StreamedResponse
{
$q = DB::table('user');
// ▼ テキスト系
if (($v = trim((string) $request->input('user_id', ''))) !== '')
$q->where('user_id', 'like', "%{$v}%");
if (($v = trim((string) $request->input('user_tag_serial', ''))) !== '')
$q->where('user_tag_serial', 'like', "%{$v}%");
if (($v = trim((string) $request->input('user_phonetic', ''))) !== '')
$q->where('user_phonetic', 'like', "%{$v}%");
if (($v = trim((string) $request->input('phone', ''))) !== '') {
$q->where(function ($w) use ($v) {
$w->where('user_mobile', 'like', "%{$v}%")
->orWhere('user_homephone', 'like', "%{$v}%");
});
}
if (($v = trim((string) $request->input('email', ''))) !== '')
$q->where('user_primemail', 'like', "%{$v}%");
// ▼ セレクト/ラジオ('' だけスキップ。'0' は適用)
$val = (string) $request->input('user_categoryid', '');
if ($val !== '')
$q->where('user_categoryid', $val);
$val = (string) $request->input('tag_qr_flag', '');
if ($val !== '')
$q->where('tag_qr_flag', (int) $val);
$val = (string) $request->input('quit_flag', '');
if ($val !== '')
$q->where('user_quit_flag', (int) $val);
// ▼ 退会日 範囲
if (($from = (string) $request->input('quit_from', '')) !== '')
$q->where('user_quitday', '>=', $from);
if (($to = (string) $request->input('quit_to', '')) !== '')
$q->where('user_quitday', '<=', $to);
// ▼ 取得・並び
$q->orderBy('user_seq', 'desc');
$rows = $q->get([
'user_id',
'tag_qr_flag',
'user_categoryid',
'user_name',
'user_phonetic',
'user_birthdate',
'user_age',
'user_mobile',
'user_homephone',
'user_primemail',
'user_idcard',
'user_idcard_chk_flag',
'user_chk_day',
'user_quit_flag',
'user_quitday',
]);
$headers = [
'利用者ID',
'タグ/QRフラグ',
'利用者分類ID',
'利用者名',
'フリガナ',
'生年月日',
'年齢',
'携帯電話番号',
'自宅電話番号',
'メールアドレス',
'本人確認書類',
'本人確認チェック済',
'本人確認日時',
'退会フラグ',
'退会日',
];
$filename = 'users_' . date('Ymd_His') . '.csv';
return response()->streamDownload(function () use ($headers, $rows) {
// ▼ BOMExcel対策
echo "\xEF\xBB\xBF";
$out = fopen('php://output', 'w');
fputcsv($out, $headers);
foreach ($rows as $r) {
// ▼ 表示値変換
$tagQr = ((int) $r->tag_qr_flag === 1) ? '' : 'タグ';
$idChk = ((int) ($r->user_idcard_chk_flag ?? 0) === 1) ? '手動チェックOK' : '未チェック';
$quitFlg = ((int) $r->user_quit_flag === 1) ? 'はい' : 'いいえ';
$birth = $r->user_birthdate ? mb_substr($r->user_birthdate, 0, 10) : '';
$chkDay = $r->user_chk_day ? mb_substr($r->user_chk_day, 0, 10) : '';
$quitDay = $r->user_quitday ? mb_substr($r->user_quitday, 0, 10) : '';
fputcsv($out, [
$r->user_id,
$tagQr,
$r->user_categoryid,
$r->user_name,
$r->user_phonetic,
$birth,
$r->user_age,
$r->user_mobile,
$r->user_homephone,
$r->user_primemail,
$r->user_idcard,
$idChk,
$chkDay,
$quitFlg,
$quitDay,
]);
}
fclose($out);
}, $filename, [
'Content-Type' => 'text/csv; charset=UTF-8',
'Content-Disposition' => 'attachment; filename="' . $filename . '"',
]);
}
/**
* 利用者登録GET: 画面表示 / POST: 登録実行)
* - 必須は最小限user_id, user_name, user_gender, user_primemail
* - created_at/updated_at は DB 側に任せるかここで now() を入れてもOK
*/
public function add(Request $request)
{
if ($request->isMethod('get')) {
return view('admin.users.add');
}
// ▼ バリデーションuser_id は半角数字のみ)
$rules = [
'user_id' => ['required', 'regex:/^\d+$/'], // 半角数字のみ許可
'user_name' => ['required', 'string', 'max:255'],
// 任意
'user_primemail' => ['nullable', 'email', 'max:255'],
'user_gender' => ['nullable', 'in:男性,女性'],
'member_id' => ['nullable', 'string', 'max:255'],
'user_mobile' => ['nullable', 'string', 'max:255'],
'user_homephone' => ['nullable', 'string', 'max:255'],
'user_birthdate' => ['nullable', 'date'],
'user_categoryid' => ['nullable', 'integer'],
];
// ▼ エラーメッセージ(日本語)
$messages = [
'user_id.required' => '利用者IDは必須です。',
'user_id.regex' => '利用者IDは半角数字のみで入力してください。',
];
// ▼ 属性名(日本語ラベル)
$attributes = [
'user_id' => '利用者ID',
'user_name' => '氏名',
'user_gender' => '性別',
'user_primemail' => '主メール',
];
$v = Validator::make($request->all(), $rules, $messages, $attributes);
if ($v->fails()) {
return back()->withErrors($v)->withInput();
}
// 実在カラム名に合わせて挿入(不要なら削る/必要なら増やす)
$data = [
'user_id' => $request->input('user_id'),
'user_name' => $request->input('user_name'),
'user_gender' => $request->input('user_gender'),
'user_primemail' => $request->input('user_primemail'),
'member_id' => $request->input('member_id'),
'user_mobile' => $request->input('user_mobile'),
'user_homephone' => $request->input('user_homephone'),
'user_birthdate' => $request->input('user_birthdate'),
'user_categoryid' => $request->input('user_categoryid'),
'created_at' => now(),
'updated_at' => now(),
];
DB::table('user')->insert($data);
return redirect()->route('users')->with('success', '利用者を登録しました。');
}
}