Files
jongryangje/app/Controllers/Admin/User.php
javamon1174 704141a1f0 CT-01/02/03 공통 컴포넌트 구현 — 페이지네이션/엑셀/인쇄
CT-01: 페이지네이션
- 커스텀 Tailwind 페이저 뷰 (components/pager.php)
- 18개 admin 컨트롤러 findAll() → paginate(20) 전환
- Bag 컨트롤러 7개 리스트도 paginate 적용
- 19개 admin index 뷰에 페이저 링크 추가

CT-02: 엑셀 저장
- export_helper.php (UTF-8 BOM CSV)
- 발주/판매/지정판매소/재고 4개 엑셀 내보내기 라우트+메서드
- 해당 뷰에 "엑셀저장" 버튼 추가

CT-03: 인쇄
- print_header.php (지자체명/제목/결재란 컴포넌트)
- admin/bag 레이아웃에 @media print CSS 추가
- 23개 뷰에 인쇄 버튼 + print_header 추가

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 16:40:49 +09:00

214 lines
8.0 KiB
PHP

<?php
namespace App\Controllers\Admin;
use App\Controllers\BaseController;
use App\Models\MemberApprovalRequestModel;
use App\Models\MemberModel;
use Config\Roles;
class User extends BaseController
{
private MemberModel $memberModel;
private MemberApprovalRequestModel $approvalModel;
private Roles $roles;
public function __construct()
{
$this->memberModel = model(MemberModel::class);
$this->approvalModel = model(MemberApprovalRequestModel::class);
$this->roles = config('Roles');
helper('pii_encryption');
}
/**
* 회원 목록
*/
public function index(): string
{
$list = $this->memberModel->orderBy('mb_idx', 'DESC')->paginate(20);
$pager = $this->memberModel->pager;
$approvalMap = [];
try {
$memberIds = array_map(static fn ($row) => (int) $row->mb_idx, $list);
if (! empty($memberIds)) {
$approvalRows = $this->approvalModel
->whereIn('mb_idx', $memberIds)
->orderBy('mar_idx', 'DESC')
->findAll();
foreach ($approvalRows as $approvalRow) {
$mbIdx = (int) $approvalRow->mb_idx;
if (! isset($approvalMap[$mbIdx])) {
$approvalMap[$mbIdx] = (string) $approvalRow->mar_status;
}
}
}
} catch (\Throwable $e) {
// 승인요청 테이블 미생성 등 예외 시 기존 상태 표시로 폴백
}
foreach ($list as $row) {
$row->mb_email = pii_decrypt($row->mb_email ?? '');
$row->mb_phone = pii_decrypt($row->mb_phone ?? '');
}
return view('admin/layout', [
'title' => '회원 관리',
'content' => view('admin/user/index', [
'list' => $list,
'roles' => $this->roles,
'approvalMap' => $approvalMap,
'pager' => $pager,
]),
]);
}
/**
* 회원 등록 폼
*/
public function create(): string
{
return view('admin/layout', [
'title' => '회원 등록',
'content' => view('admin/user/create', [
'roles' => $this->roles,
'assignableLevels' => $this->getAssignableLevels(),
]),
]);
}
/**
* 회원 등록 처리
*/
public function store()
{
$rules = [
'mb_id' => 'required|min_length[2]|max_length[50]|is_unique[member.mb_id]',
'mb_passwd' => 'required|min_length[4]|max_length[255]',
'mb_name' => 'required|max_length[50]',
'mb_email' => 'permit_empty|valid_email|max_length[100]',
'mb_phone' => 'permit_empty|max_length[20]',
'mb_level' => 'required',
];
if (! $this->validate($rules)) {
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$allowedLevels = array_keys($this->getAssignableLevels());
$requestedLevel = (int) $this->request->getPost('mb_level');
if (! in_array($requestedLevel, $allowedLevels, true)) {
return redirect()->back()->withInput()->with('error', '현재 권한으로는 해당 역할을 등록할 수 없습니다.');
}
$data = [
'mb_id' => $this->request->getPost('mb_id'),
'mb_passwd' => password_hash((string) $this->request->getPost('mb_passwd'), PASSWORD_DEFAULT),
'mb_name' => $this->request->getPost('mb_name'),
'mb_email' => pii_encrypt($this->request->getPost('mb_email')),
'mb_phone' => pii_encrypt($this->request->getPost('mb_phone')),
'mb_level' => $requestedLevel,
'mb_state' => 1,
'mb_regdate' => date('Y-m-d H:i:s'),
'mb_latestdate' => null,
];
$this->memberModel->insert($data);
return redirect()->to(site_url('admin/users'))->with('success', '회원이 등록되었습니다.');
}
/**
* 회원 수정 폼
*/
public function edit(int $id): string
{
$member = $this->memberModel->find($id);
if (! $member) {
return redirect()->to(site_url('admin/users'))->with('error', '회원을 찾을 수 없습니다.');
}
$member->mb_email = pii_decrypt($member->mb_email ?? '');
$member->mb_phone = pii_decrypt($member->mb_phone ?? '');
return view('admin/layout', [
'title' => '회원 수정',
'content' => view('admin/user/edit', [
'member' => $member,
'roles' => $this->roles,
'assignableLevels' => $this->getAssignableLevels(),
]),
]);
}
/**
* 회원 수정 처리
*/
public function update(int $id)
{
$member = $this->memberModel->find($id);
if (! $member) {
return redirect()->to(site_url('admin/users'))->with('error', '회원을 찾을 수 없습니다.');
}
$rules = [
'mb_id' => "required|min_length[2]|max_length[50]|is_unique[member.mb_id,mb_idx,{$id}]",
'mb_name' => 'required|max_length[50]',
'mb_email' => 'permit_empty|valid_email|max_length[100]',
'mb_phone' => 'permit_empty|max_length[20]',
'mb_level' => 'required',
'mb_state' => 'required|in_list[0,1,2]',
];
$passwd = $this->request->getPost('mb_passwd');
if ($passwd !== '') {
$rules['mb_passwd'] = 'min_length[4]|max_length[255]';
}
if (! $this->validate($rules)) {
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$allowedLevels = array_keys($this->getAssignableLevels());
$requestedLevel = (int) $this->request->getPost('mb_level');
if (! in_array($requestedLevel, $allowedLevels, true)) {
return redirect()->back()->withInput()->with('error', '현재 권한으로는 해당 역할로 수정할 수 없습니다.');
}
$data = [
'mb_id' => $this->request->getPost('mb_id'),
'mb_name' => $this->request->getPost('mb_name'),
'mb_email' => pii_encrypt($this->request->getPost('mb_email')),
'mb_phone' => pii_encrypt($this->request->getPost('mb_phone')),
'mb_level' => $requestedLevel,
'mb_state' => (int) $this->request->getPost('mb_state'),
];
if ($passwd !== '') {
$data['mb_passwd'] = password_hash($passwd, PASSWORD_DEFAULT);
}
$this->memberModel->update($id, $data);
return redirect()->to(site_url('admin/users'))->with('success', '회원 정보가 수정되었습니다.');
}
/**
* 현재 로그인한 관리자가 부여 가능한 역할 목록.
* super/본부만 4·5 부여 가능, 지자체 관리자는 1~3만.
*
* @return array<int,string>
*/
private function getAssignableLevels(): array
{
$levelNames = $this->roles->levelNames;
$myLevel = (int) session()->get('mb_level');
if (Roles::isSuperAdminEquivalent($myLevel)) {
return $levelNames;
}
unset($levelNames[Roles::LEVEL_SUPER_ADMIN], $levelNames[Roles::LEVEL_HEADQUARTERS_ADMIN]);
return $levelNames;
}
/**
* 회원 삭제(탈퇴 처리: mb_state=0, mb_leavedate 기록)
*/
public function delete(int $id)
{
$member = $this->memberModel->find($id);
if (! $member) {
return redirect()->to(site_url('admin/users'))->with('error', '회원을 찾을 수 없습니다.');
}
$this->memberModel->update($id, [
'mb_state' => 0,
'mb_leavedate' => date('Y-m-d H:i:s'),
]);
return redirect()->to(site_url('admin/users'))->with('success', '회원이 탈퇴 처리되었습니다.');
}
}