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>
141 lines
5.6 KiB
PHP
141 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Admin;
|
|
|
|
use App\Controllers\BaseController;
|
|
use App\Models\LocalGovernmentModel;
|
|
use App\Models\MemberApprovalRequestModel;
|
|
use App\Models\MemberModel;
|
|
use Config\Roles;
|
|
use App\Models\MemberLogModel;
|
|
|
|
class Access extends BaseController
|
|
{
|
|
private MemberLogModel $memberLogModel;
|
|
private MemberApprovalRequestModel $approvalModel;
|
|
private MemberModel $memberModel;
|
|
private Roles $roles;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->memberLogModel = model(MemberLogModel::class);
|
|
$this->approvalModel = model(MemberApprovalRequestModel::class);
|
|
$this->memberModel = model(MemberModel::class);
|
|
$this->roles = config('Roles');
|
|
}
|
|
|
|
/**
|
|
* 로그인 이력 (기간 조회)
|
|
*/
|
|
public function loginHistory(): string
|
|
{
|
|
$start = $this->request->getGet('start');
|
|
$end = $this->request->getGet('end');
|
|
$builder = $this->memberLogModel;
|
|
$builder->orderBy('mll_regdate', 'DESC');
|
|
if ($start !== null && $start !== '') {
|
|
$builder->where('mll_regdate >=', $start . ' 00:00:00');
|
|
}
|
|
if ($end !== null && $end !== '') {
|
|
$builder->where('mll_regdate <=', $end . ' 23:59:59');
|
|
}
|
|
$list = $builder->paginate(20);
|
|
$pager = $this->memberLogModel->pager;
|
|
return view('admin/layout', [
|
|
'title' => '로그인 이력',
|
|
'content' => view('admin/access/login_history', ['list' => $list, 'start' => $start, 'end' => $end, 'pager' => $pager]),
|
|
]);
|
|
}
|
|
|
|
public function approvals(): string
|
|
{
|
|
$status = (string) ($this->request->getGet('status') ?? MemberApprovalRequestModel::STATUS_PENDING);
|
|
$allowedStatus = [
|
|
MemberApprovalRequestModel::STATUS_PENDING,
|
|
MemberApprovalRequestModel::STATUS_APPROVED,
|
|
MemberApprovalRequestModel::STATUS_REJECTED,
|
|
];
|
|
if (! in_array($status, $allowedStatus, true)) {
|
|
$status = MemberApprovalRequestModel::STATUS_PENDING;
|
|
}
|
|
|
|
$list = $this->approvalModel
|
|
->select('member_approval_request.*, member.mb_id, member.mb_name, member.mb_lg_idx, local_government.lg_name')
|
|
->join('member', 'member.mb_idx = member_approval_request.mb_idx', 'left')
|
|
->join('local_government', 'local_government.lg_idx = member.mb_lg_idx', 'left')
|
|
->where('member_approval_request.mar_status', $status)
|
|
->orderBy('member_approval_request.mar_requested_at', 'DESC')
|
|
->paginate(20);
|
|
$pager = $this->approvalModel->pager;
|
|
|
|
return view('admin/layout', [
|
|
'title' => '승인 대기',
|
|
'content' => view('admin/access/approvals', [
|
|
'list' => $list,
|
|
'status' => $status,
|
|
'roles' => $this->roles,
|
|
'pager' => $pager,
|
|
]),
|
|
]);
|
|
}
|
|
|
|
public function approve(int $id)
|
|
{
|
|
$requestRow = $this->approvalModel->find($id);
|
|
if (! $requestRow) {
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('error', '승인 요청을 찾을 수 없습니다.');
|
|
}
|
|
if ($requestRow->mar_status !== MemberApprovalRequestModel::STATUS_PENDING) {
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('error', '이미 처리된 요청입니다.');
|
|
}
|
|
|
|
$requestedLevel = (int) $requestRow->mar_requested_level;
|
|
if ($requestedLevel === Roles::LEVEL_SUPER_ADMIN || $requestedLevel === Roles::LEVEL_HEADQUARTERS_ADMIN) {
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('error', '상위 관리자 역할 요청은 승인할 수 없습니다.');
|
|
}
|
|
|
|
$db = db_connect();
|
|
$db->transStart();
|
|
$this->memberModel->update((int) $requestRow->mb_idx, [
|
|
'mb_level' => $requestedLevel,
|
|
]);
|
|
$this->approvalModel->update($id, [
|
|
'mar_status' => MemberApprovalRequestModel::STATUS_APPROVED,
|
|
'mar_processed_at' => date('Y-m-d H:i:s'),
|
|
'mar_processed_by' => (int) (session()->get('mb_idx') ?? 0),
|
|
'mar_reject_reason' => null,
|
|
]);
|
|
$db->transComplete();
|
|
|
|
if (! $db->transStatus()) {
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('error', '승인 처리 중 오류가 발생했습니다.');
|
|
}
|
|
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('success', '승인 처리되었습니다.');
|
|
}
|
|
|
|
public function reject(int $id)
|
|
{
|
|
$requestRow = $this->approvalModel->find($id);
|
|
if (! $requestRow) {
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('error', '승인 요청을 찾을 수 없습니다.');
|
|
}
|
|
if ($requestRow->mar_status !== MemberApprovalRequestModel::STATUS_PENDING) {
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('error', '이미 처리된 요청입니다.');
|
|
}
|
|
|
|
$reason = trim((string) $this->request->getPost('reject_reason'));
|
|
if ($reason === '') {
|
|
$reason = '관리자 반려';
|
|
}
|
|
$this->approvalModel->update($id, [
|
|
'mar_status' => MemberApprovalRequestModel::STATUS_REJECTED,
|
|
'mar_reject_reason' => mb_substr($reason, 0, 255),
|
|
'mar_processed_at' => date('Y-m-d H:i:s'),
|
|
'mar_processed_by' => (int) (session()->get('mb_idx') ?? 0),
|
|
]);
|
|
|
|
return redirect()->to(site_url('admin/access/approvals'))->with('success', '반려 처리되었습니다.');
|
|
}
|
|
}
|