From 365d0a9af91bdc6a153d6a42d3bdbe6163cb6575 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B5=9C=EC=A4=80=ED=9D=A0?= Date: Thu, 20 Nov 2025 11:26:53 +0900 Subject: [PATCH] dbmsv4 init...1 --- app/Controllers/AbstractWebController.php | 1 + app/Controllers/Admin/AdminController.php | 2 +- app/Controllers/Admin/PaymentController.php | 47 ++++++++++----- app/Controllers/CommonController.php | 15 ++--- app/DTOs/Customer/ClientDTO.php | 15 ++++- app/Entities/Customer/ClientEntity.php | 57 +++++++++++++++++-- app/Forms/BoardForm.php | 3 +- app/Forms/CollectorForm.php | 46 --------------- app/Forms/CommonForm.php | 6 +- app/Forms/PaymentForm.php | 18 ++++++ app/Helpers/CommonHelper.php | 19 ++++--- app/Helpers/Customer/ClientHelper.php | 24 ++++++++ app/Helpers/Customer/ServiceHelper.php | 2 +- app/Views/cells/service/payment.php | 2 +- app/Views/layouts/admin/left_menu/base.php | 3 + .../layouts/admin/left_menu/customer.php | 3 - 16 files changed, 170 insertions(+), 93 deletions(-) delete mode 100644 app/Forms/CollectorForm.php diff --git a/app/Controllers/AbstractWebController.php b/app/Controllers/AbstractWebController.php index ef2ceb5..5265175 100644 --- a/app/Controllers/AbstractWebController.php +++ b/app/Controllers/AbstractWebController.php @@ -112,6 +112,7 @@ abstract class AbstractWebController extends Controller */ protected function action_render_process(string $view_file, array $viewDatas, ?string $template_path = null): string { + // dd($viewDatas); $view_path = $viewDatas['layout']; if ($template_path) { $view_path .= DIRECTORY_SEPARATOR . $template_path; diff --git a/app/Controllers/Admin/AdminController.php b/app/Controllers/Admin/AdminController.php index 9879dc0..b7283c3 100644 --- a/app/Controllers/Admin/AdminController.php +++ b/app/Controllers/Admin/AdminController.php @@ -20,6 +20,7 @@ abstract class AdminController extends CommonController } protected function action_init_process(string $action): void { + parent::action_init_process($action); $this->addViewDatas('layout', $this->getLayout()); $this->addViewDatas('helper', $this->service->getHelper()); $this->addViewDatas('formFields', $this->service->getFormService()->getFormFields()); @@ -29,6 +30,5 @@ abstract class AdminController extends CommonController $this->addViewDatas('index_actionButtons', $this->service->getFormService()->getactionButtons()); $this->addViewDatas('index_batchjobFields', $this->service->getFormService()->getBatchjobFilters()); $this->addViewDatas('index_batchjobButtons', $this->service->getFormService()->getBatchjobButtons()); - parent::action_init_process($action); } } diff --git a/app/Controllers/Admin/PaymentController.php b/app/Controllers/Admin/PaymentController.php index cc29098..f617908 100644 --- a/app/Controllers/Admin/PaymentController.php +++ b/app/Controllers/Admin/PaymentController.php @@ -3,13 +3,9 @@ namespace App\Controllers\Admin; use App\Entities\PaymentEntity; -use CodeIgniter\HTTP\DownloadResponse; -use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; -use CodeIgniter\Validation\Exceptions\ValidationException; use Psr\Log\LoggerInterface; -use RuntimeException; class PaymentController extends AdminController { @@ -25,19 +21,14 @@ class PaymentController extends AdminController protected function action_init_process(string $action): void { $fields = [ - "clientinfo_uid", "serviceinfo_uid", - "serverpartinfo_uid", "title", - "content", "amount", "billing", "billing_at", - "pay", - "status", - "updated_at" + "content ", ]; - $filters = ['role', 'status']; + $filters = ['clientinfo_uid', 'serviceinfo_uid', 'status', 'billing', 'pay']; $batchjobFilters = ['status']; // $actionButtons = ['view' => ICONS['SEARCH']]; // $batchjobButtons = []; @@ -47,14 +38,42 @@ class PaymentController extends AdminController break; case 'modify': case 'modify_form': - $fields = ['title', 'amount', 'pay', 'status']; + $fields = ['title', 'amount', 'pay', 'status', 'content']; break; case 'view': - $fields = [...$fields, 'created_at']; + $fields = [ + ...$fields, + 'clientinfo_uid', + "serviceinfo_uid", + 'billing', + 'title', + 'amount', + 'billing_at', + 'pay', + 'status', + 'updated_at', + 'countdown', + 'user_uid', + 'created_at', + 'content' + ]; break; case 'index': case 'download': - $fields = [...$fields, 'created_at']; + $fields = [ + 'clientinfo_uid', + "serviceinfo_uid", + 'billing', + 'title', + 'amount', + 'billing_at', + 'pay', + 'status', + 'updated_at', + 'countdown', + 'user_uid', + 'created_at' + ]; break; default: throw new \Exception("[{$action}] 지원하지 않는 action입니다."); diff --git a/app/Controllers/CommonController.php b/app/Controllers/CommonController.php index dd6602d..9099f6e 100644 --- a/app/Controllers/CommonController.php +++ b/app/Controllers/CommonController.php @@ -235,7 +235,6 @@ abstract class CommonController extends AbstractCRUDController $perpage = (int) $this->request->getVar('perpage') ?: intval(DEFAULTS['INDEX_PERPAGE'] ?? 10); $this->addViewDatas('page', $page); $this->addViewDatas('perpage', $perpage); - // 1. Total Count 계산을 위한 조건절 처리 (오버라이드 가능) $this->index_condition_process($action); $index_totalcount = $this->service->getTotalCount(); @@ -244,7 +243,6 @@ abstract class CommonController extends AbstractCRUDController // Pagination 설정 $this->addViewDatas('index_pagination', $this->pagenation_process($index_totalcount, $page, $perpage)); $this->addViewDatas('index_pagination_options', $this->pagenation_options_process($index_totalcount, $perpage)); - // 2. 실제 리스트를 위한 조건절, LIMIT, OFFSET 처리 (오버라이드 가능) $this->index_condition_process($action); // 조건절을 다시 호출하여 필터/검색어 유지 $this->service->setLimit($perpage); @@ -256,16 +254,11 @@ abstract class CommonController extends AbstractCRUDController $this->addViewDatas('formDatas', $this->request->getVar() ?? []); } - final public function index(): string|ResponseInterface + final public function index(): string { - try { - $action = __FUNCTION__; - $this->action_init_process($action); - $this->index_process($action); - $this->index_result_process($action); - } catch (\Exception $e) { - session()->setFlashdata('message', $e->getMessage()); - } + $action = __FUNCTION__; + $this->action_init_process($action); + $this->index_process($action); return $this->index_result_process($action); } diff --git a/app/DTOs/Customer/ClientDTO.php b/app/DTOs/Customer/ClientDTO.php index 190a4c2..8892499 100644 --- a/app/DTOs/Customer/ClientDTO.php +++ b/app/DTOs/Customer/ClientDTO.php @@ -24,8 +24,21 @@ class ClientDTO extends CommonDTO parent::__construct(); foreach ($datas as $key => $value) { if (property_exists($this, $key)) { - $this->{$key} = $value; + if ($key === 'role' && is_array($value)) { + // 배열일 경우, 쉼표로 구분된 문자열로 변환하여 저장 + $this->role = implode(DEFAULTS["DELIMITER_ROLE"], $value); + } else { + $this->{$key} = $value; + } } } } + public function __get(string $name) + { + // 'role' 속성을 요청했을 때만 특별히 처리 + if ($name === 'role' && is_string($this->role)) { + return explode(DEFAULTS["DELIMITER_ROLE"], $this->role); + } + return parent::__get($name); + } } diff --git a/app/Entities/Customer/ClientEntity.php b/app/Entities/Customer/ClientEntity.php index 449f786..15f1207 100644 --- a/app/Entities/Customer/ClientEntity.php +++ b/app/Entities/Customer/ClientEntity.php @@ -26,10 +26,6 @@ class ClientEntity extends CustomerEntity { return $this->attributes['site']; } - public function getRole(): string - { - return $this->attributes['role']; - } public function getAccountBalance(): int { return $this->attributes['account_balance']; @@ -46,4 +42,57 @@ class ClientEntity extends CustomerEntity { return $this->attributes['history']; } + /* + * 사용자의 역할을 배열 형태로 반환합니다. + * DB의 JSON 또는 CSV 형식 데이터를 모두 배열로 복구할 수 있는 로직을 포함합니다. + * @return array + */ + public function getRole(): array + { + $role = $this->attributes['role'] ?? null; + // 1. 이미 배열인 경우 (방어적 코딩) + if (is_array($role)) { + return array_filter($role); + } + // 2. 문자열 데이터인 경우 처리 + if (is_string($role) && !empty($role)) { + // 2-a. JSON 디코딩 시도 (기존 DB의 JSON 형식 처리) + $decodedRole = json_decode($role, true); + if (json_last_error() === JSON_ERROR_NONE && is_array($decodedRole)) { + return $decodedRole; + } + // 2-b. JSON이 아니면 CSV로 가정하고 변환 + $parts = explode(',', $role); + // 각 요소의 불필요한 공백과 따옴표 제거 + $cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $parts); + return array_filter($cleanedRoles); + } + // 3. 변환에 실패했거나 데이터가 없는 경우 빈 배열 반환 + return []; + } + // --- Setter Methods --- + + /** + * Role 데이터가 Entity에 설정될 때 호출되어, 입력된 CSV/JSON 문자열을 정리 후 + * DB에 적합한 CSV 문자열로 최종 저장합니다. + * @param mixed $role 입력 데이터 (문자열 또는 배열) + */ + public function setRole(mixed $role) + { + $roleArray = []; + if (is_string($role)) { + // 1. 양쪽의 불필요한 따옴표와 공백을 제거하여 깨끗한 문자열 확보 + $cleanRoleString = trim($role, " \t\n\r\0\x0B\""); + if (!empty($cleanRoleString)) { + $role = explode(DEFAULTS["DELIMITER_ROLE"], $cleanRoleString); + } + } + if (is_array($role)) { + //배열에도 불필요한 따옴표와 공백을 제거 + $cleanedRoles = array_map(fn($item) => trim($item, " \t\n\r\0\x0B\""), $role); + $roleArray = array_filter($cleanedRoles); + } + // 💡 핵심: 최종적으로 DB에 삽입될 단일 CSV 문자열로 변환하여 저장합니다. + $this->attributes['role'] = implode(DEFAULTS["DELIMITER_ROLE"], $roleArray); + } } diff --git a/app/Forms/BoardForm.php b/app/Forms/BoardForm.php index 2d519d4..9e5c5d3 100644 --- a/app/Forms/BoardForm.php +++ b/app/Forms/BoardForm.php @@ -44,8 +44,9 @@ class BoardForm extends CommonForm } return $rule; } - public function getFormOption(string $field, array $options = []): array + public function getFormOption(string $field, array $options = ['options' => [], 'extras' => [], 'atttributes' => []]): array { + $tempOptions = ['' => lang("{$this->getAttribute('class_path')}.label.{$field}") . " 선택"]; switch ($field) { case 'worker_uid': foreach (service('userservice')->getEntities() as $entity) { diff --git a/app/Forms/CollectorForm.php b/app/Forms/CollectorForm.php deleted file mode 100644 index 1e42ed3..0000000 --- a/app/Forms/CollectorForm.php +++ /dev/null @@ -1,46 +0,0 @@ - [], 'extras' => [], 'atttributes' => []]): array - { - $tempOptions = ['' => lang("{$this->getAttribute('class_path')}.label.{$field}") . " 선택"]; - switch ($field) { - case 'trafficinfo_uid': - foreach (service('trafficservice')->getEntities() as $entity) { - $tempOptions[$entity->getPK()] = $entity->getCustomTitle(); - } - $options['options'] = $tempOptions; - break; - default: - $options = parent::getFormOption($field, $options); - break; - } - return $options; - } -} diff --git a/app/Forms/CommonForm.php b/app/Forms/CommonForm.php index a2f3140..5181167 100644 --- a/app/Forms/CommonForm.php +++ b/app/Forms/CommonForm.php @@ -194,7 +194,11 @@ abstract class CommonForm $options['options'] = $tempOptions; break; default: - foreach (lang($this->getAttribute('class_path') . "." . strtoupper($field)) as $key => $label) { + $optionDatas = lang($this->getAttribute('class_path') . "." . strtoupper($field)); + if (!is_array($optionDatas)) { + throw new \Exception(__METHOD__ . "에서 오류발생:{$field}가 배열값이 아닙니다."); + } + foreach ($optionDatas as $key => $label) { $tempOptions[$key] = $label; } $options['options'] = $tempOptions; diff --git a/app/Forms/PaymentForm.php b/app/Forms/PaymentForm.php index f38ac1a..d746c82 100644 --- a/app/Forms/PaymentForm.php +++ b/app/Forms/PaymentForm.php @@ -40,4 +40,22 @@ class PaymentForm extends CommonForm } return $rule; } + + public function getFormOption(string $field, array $options = ['options' => [], 'extras' => [], 'atttributes' => []]): array + { + $tempOptions = ['' => lang("{$this->getAttribute('class_path')}.label.{$field}") . " 선택"]; + switch ($field) { + case 'serviceinfo_uid': + foreach (service('customer_serviceservice')->getEntities() as $entity) { + $tempOptions[$entity->getPK()] = $entity->getTitle(); + // $options['attributes'][$entity->getPK()] = ['data-role' => implode(DEFAULTS['DELIMITER_ROLE'], $entity->getRole())]; + } + $options['options'] = $tempOptions; + break; + default: + $options = parent::getFormOption($field, $options); + break; + } + return $options; + } } diff --git a/app/Helpers/CommonHelper.php b/app/Helpers/CommonHelper.php index e367453..b3096e4 100644 --- a/app/Helpers/CommonHelper.php +++ b/app/Helpers/CommonHelper.php @@ -123,7 +123,10 @@ abstract class CommonHelper default: $extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' form-control' : 'form-control'; if (in_array($field, $viewDatas['formFilters'])) { - $form = form_dropdown($field, $viewDatas['formOptions'][$field]['options'], $value, [...$extras, ...$viewDatas['formOptions'][$field]['extras']]); + if (array_key_exists('extras', $viewDatas['formOptions'][$field])) { + $extras = array_merge($extras, $viewDatas['formOptions'][$field]['extras']); + } + $form = form_dropdown($field, $viewDatas['formOptions'][$field]['options'], $value, $extras); } else { $extras['style'] = 'width:100%;'; $form = form_input($field, $value ?? "", $extras); @@ -141,9 +144,12 @@ abstract class CommonHelper } break; case 'role': + if (!is_array($value)) { //배열이 아니면 + $value = explode(DEFAULTS['DELIMITER_ROLE'], $value); + } $roles = []; foreach ($value as $key) { - $roles[] = $viewDatas['formOptions'][$field]['options'][$key] ?? ""; + $roles[] = $viewDatas['formOptions'][$field]['options'][$key]; } $value = implode(" , ", $roles); break; @@ -167,7 +173,7 @@ abstract class CommonHelper break; default: if (in_array($field, $viewDatas['formFilters'])) { - $value = $viewDatas['formOptions'][$field]['options'][$value] ?? ""; + $value = $viewDatas['formOptions'][$field]['options'][$value]; } break; } @@ -182,12 +188,7 @@ abstract class CommonHelper default: $filter = ""; if (in_array($field, $viewDatas['formFilters'])) { - $filter = form_dropdown( - $field, - $viewDatas['formOptions'][$field]['options'], - $value, - [...$extras, ...$viewDatas['formOptions'][$field]['extras']] - ); + $filter = form_dropdown($field, $viewDatas['formOptions'][$field]['options'], $value, $extras); } break; } diff --git a/app/Helpers/Customer/ClientHelper.php b/app/Helpers/Customer/ClientHelper.php index abcb5f9..874aae2 100644 --- a/app/Helpers/Customer/ClientHelper.php +++ b/app/Helpers/Customer/ClientHelper.php @@ -8,6 +8,30 @@ class ClientHelper extends CustomerHelper { parent::__construct(); } + public function getFieldForm(string $field, mixed $value, array $viewDatas, array $extras = []): string + { + switch ($field) { + case 'role': + $currentRoles = is_array($value) + ? array_map('strtolower', array_map('trim', $value)) + : []; + $form = ''; + //Form페이지에서는 맨앞에것 제외하기 위함 + $firstOption = array_shift($viewDatas['formOptions'][$field]['options']); + foreach ($viewDatas['formOptions'][$field]['options'] as $key => $label) { + $checked = in_array(strtolower(trim($key)), $currentRoles); + $form .= ''; + } + break; + default: + $form = parent::getFieldForm($field, $value, $viewDatas, $extras); + break; + } + return $form; + } // public function getFieldView(string $field, mixed $value, array $viewDatas, array $extras = []): string|null { switch ($field) { diff --git a/app/Helpers/Customer/ServiceHelper.php b/app/Helpers/Customer/ServiceHelper.php index 11b3466..55053a4 100644 --- a/app/Helpers/Customer/ServiceHelper.php +++ b/app/Helpers/Customer/ServiceHelper.php @@ -40,7 +40,7 @@ class ServiceHelper extends CustomerHelper if (array_key_exists('unPaids', $viewDatas)) { if (array_key_exists($viewDatas['entity']->getPK(), $viewDatas['unPaids'])) { $value .= sprintf( - "
%s개,총 %s원
", + "
%s개,총 %s원
", $viewDatas['entity']->getPK(), $viewDatas['unPaids'][$viewDatas['entity']->getPK()]['cnt'], number_format($viewDatas['unPaids'][$viewDatas['entity']->getPK()]['amount']) diff --git a/app/Views/cells/service/payment.php b/app/Views/cells/service/payment.php index 9c97cba..ed1f0f8 100644 --- a/app/Views/cells/service/payment.php +++ b/app/Views/cells/service/payment.php @@ -16,7 +16,7 @@ sprintf("총:%s건/%s원", $serviceCellDatas['unPaids'][$serviceEntity->getPK()]['cnt'], number_format($serviceCellDatas['unPaids'][$serviceEntity->getPK()]['amount'])), 'payment_unpaid', [ - "data-src" => "/admin/customer/payment?clientinfo_uid={$serviceEntity->getClientInfoUID()}&serviceinfo_uid={$serviceEntity->getPK()}&status=unpaid&ActionTemplate=popup", + "data-src" => "/admin/payment?clientinfo_uid={$serviceEntity->getClientInfoUID()}&serviceinfo_uid={$serviceEntity->getPK()}&status=unpaid&ActionTemplate=popup", "data-bs-toggle" => "modal", "data-bs-target" => "#modal_action_form", "class" => "text-primary form-label-sm", diff --git a/app/Views/layouts/admin/left_menu/base.php b/app/Views/layouts/admin/left_menu/base.php index aeed902..9a09de4 100644 --- a/app/Views/layouts/admin/left_menu/base.php +++ b/app/Views/layouts/admin/left_menu/base.php @@ -1,3 +1,6 @@
계정 관리 +
+
+ 결제내역
\ No newline at end of file diff --git a/app/Views/layouts/admin/left_menu/customer.php b/app/Views/layouts/admin/left_menu/customer.php index 758c627..5275650 100644 --- a/app/Views/layouts/admin/left_menu/customer.php +++ b/app/Views/layouts/admin/left_menu/customer.php @@ -11,7 +11,4 @@
서비스내역
-
- 결제내역 -
\ No newline at end of file