trafficmonitor init...2

This commit is contained in:
choi.jh 2025-11-17 14:57:40 +09:00
parent a07b0f238a
commit 58680bacb2
2 changed files with 138 additions and 48 deletions

4
.gitignore vendored
View File

@ -13,5 +13,5 @@ writable/uploads/*
!writable/uploads/index.html
writable/debugbar/*
!writable/debugbar/index.html
writable/excel/*
!writable/excel/index.html
writable/download/*
!writable/download/index.html

View File

@ -1,58 +1,148 @@
<?= $this->extend(LAYOUTS[$viewDatas['layout']]['path']) ?>
<?php
$layouts = LAYOUTS[$viewDatas['layout']];
// PHP 변수들은 그대로 사용하지만, 데이터(entities)는 비어있는 상태로 전달됩니다.
$layouts = LAYOUTS[$viewDatas['layout']]['path'];
$template = "templates" . DIRECTORY_SEPARATOR . "{$viewDatas['layout']}";
// API 엔드포인트를 JS에서 사용하기 위해 PHP에서 설정합니다.
// 예: '/api/items' 또는 $viewDatas['apiEndpoint'] 변수를 사용
$apiEndpoint = '/api/example/listitems';
?>
<?= $this->section('content') ?>
<?= session('message') ? $viewDatas['helper']->alertTrait(session('message')) : ""; ?>
<div class="layout_top"><?= $this->include("{$layouts['path']}/top"); ?></div>
<div class="layout_top"><?= $this->include("{$layouts}/top"); ?></div>
<table class="layout_middle">
<tr>
<td class="layout_left"><?= $this->include("{$layouts['path']}/left_menu"); ?></td>
<td class="layout_right">
<div class="layout_header"><?= $this->include("{$template}/index_header"); ?></div>
<div id="container" class="layout_content">
  <tr>
    <td class="layout_left"><?= $this->include("{$layouts}/left_menu"); ?></td>
    <td class="layout_right">
      <div class="layout_header"><?= $this->include("{$template}/index_header"); ?></div>
      <div id="container" class="layout_content">
       
<link href="/css/<?= $viewDatas['layout'] ?>/index.css" media="screen" rel="stylesheet" type="text/css" />
<div class="index_body">
<?= $this->include("{$template}/index_content_filter"); ?>
<?= form_open(current_url(), ['id' => 'batchjob_form', 'method' => "post"]) ?>
<table class="index_table data table table-bordered table-hover table-striped" data-rtc-resizable-table="reisze_table">
<thead>
<tr>
<th class="text-center bg-light">번호</th>
<?php foreach ($viewDatas['formFields'] as $field => $label): ?>
<th class="text-center bg-light"><?= $viewDatas['helper']->getListLabel($field, $label, $viewDatas) ?></th>
<?php endforeach ?>
<th class="text-center bg-light">작업</th>
        <div class="index_body">
          <?= $this->include("{$template}/index_content_filter"); ?>
          <?= form_open(current_url(), ['id' => 'batchjob_form', 'method' => "post"]) ?>
          <table class="index_table data table table-bordered table-hover table-striped" data-rtc-resizable-table="reisze_table">
            <thead>
              <tr>
                <th class="text-center bg-light">번호</th>
                <?php foreach ($viewDatas['formFields'] as $field => $label): ?>
                  <th class="text-center bg-light"><?= $viewDatas['helper']->getListLabel($field, $label, $viewDatas) ?></th>
                <?php endforeach ?>
                <th class="text-center bg-light">작업</th>
              </tr>
            </thead>
            <!-- 데이터가 동적으로 채워질 영역: 기존 PHP 루프 대신 ID 부여 -->
            <tbody id="data_list_tbody">
              <tr>
<td colspan="<?= count($viewDatas['formFields']) + 2 ?>" class="text-center text-secondary p-5">데이터를 불러오는 중입니다...</td>
</tr>
</thead>
<tbody>
<?php $cnt = 0 ?>
<?php foreach ($viewDatas['entities'] as $entity): ?>
<?php
$viewDatas['entity'] = $entity;
$num = $viewDatas['index_totalcount'] - (($viewDatas['page'] - 1) * $viewDatas['perpage'] + $cnt);
?>
<tr>
<td nowrap><?= $viewDatas['helper']->getListButton('modify', $num, $viewDatas) ?></td>
<?php foreach ($viewDatas['formFields'] as $field => $label): ?><td><?= $viewDatas['helper']->getFieldView($field, $entity->$field, $viewDatas) ?></td><?php endforeach ?>
<td nowrap>
<?php foreach ($viewDatas['index_actionButtons'] as $action => $label): ?>
<?= $viewDatas['helper']->getListButton($action, $label, $viewDatas) ?>&nbsp;
<?php endforeach ?>
</td>
</tr>
<?php $cnt++ ?>
<?php endforeach ?>
</tbody>
</table>
<?= $this->include("{$template}/index_content_bottom"); ?>
<?= form_close() ?>
</div>
            </tbody>
          </table>
          <?= $this->include("{$template}/index_content_bottom"); ?>
          <?= form_close() ?>
        </div>
     
</div>
<div class="layout_footer"><?= $this->include("{$template}/index_footer"); ?></div>
</td>
</tr>
      <div class="layout_footer"><?= $this->include("{$template}/index_footer"); ?></div>
    </td>
  </tr>
</table>
<div class="layout_bottom"><?= $this->include("{$layouts['path']}/bottom"); ?></div>
<div class="layout_bottom"><?= $this->include("{$layouts}/bottom"); ?></div>
<!-- 2. API Call JavaScript 추가 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const tbody = document.getElementById('data_list_tbody');
const apiEndpoint = '<?= $apiEndpoint ?>'; // PHP에서 설정한 API 경로
async function fetchData() {
// 로딩 상태 표시
tbody.innerHTML = `<tr><td colspan="<?= count($viewDatas['formFields']) + 2 ?>" class="text-center text-info p-5">데이터 로드 중...</td></tr>`;
try {
const response = await fetch(apiEndpoint);
if (!response.ok) {
throw new Error('API 호출 실패: ' + response.statusText);
}
const result = await response.json();
// API 응답 구조를 확인하여 데이터 배열을 추출 (여기서는 result.data라고 가정)
if (result.status === 'success' && Array.isArray(result.data)) {
renderTable(result.data);
} else {
throw new Error(result.message || '데이터 구조 오류');
}
} catch (error) {
console.error("데이터 로드 오류:", error);
tbody.innerHTML = `<tr><td colspan="<?= count($viewDatas['formFields']) + 2 ?>" class="text-center text-danger p-5">목록을 불러오는 데 실패했습니다. (${error.message})</td></tr>`;
}
}
/**
* API에서 받은 데이터 배열을 기반으로 테이블 본문을 렌더링합니다.
* * 주의: 부분은 클라이언트(JS)에서 HTML을 생성하므로,
* 기존 PHP Helper($viewDatas['helper']) 사용할 없어 순수 HTML 문자열을 구성해야 합니다.
* 동적 필드 렌더링($viewDatas['helper']->getFieldView) 로직은 JS로 옮겨야 합니다.
* 아래는 **가장 단순화된 예시**입니다.
*/
function renderTable(entities) {
if (entities.length === 0) {
tbody.innerHTML = `<tr><td colspan="<?= count($viewDatas['formFields']) + 2 ?>" class="text-center text-muted p-5">조회된 데이터가 없습니다.</td></tr>`;
return;
}
let html = '';
// 실제로는 전체 건수와 페이지당 개수를 알아야 정확한 번호를 계산할 수 있지만,
// 여기서는 예시로 인덱스 기반 번호를 사용합니다.
let num = entities.length;
const formFields = <?= json_encode(array_keys($viewDatas['formFields'])) ?>;
entities.forEach((entity, index) => {
html += '<tr>';
// 1. 번호 (getListButton('modify', ...)) - 단순화
// 원본 코드를 완벽히 재현하려면 modify 버튼 로직을 JS로 구현해야 합니다.
html += `<td nowrap>${num - index}</td>`;
// 2. 데이터 필드
formFields.forEach(field => {
// $entity->$field 대신 entity[field] 사용.
// $viewDatas['helper']->getFieldView 로직을 단순하게 출력으로 대체.
// 실제 프로젝트에서는 이 부분을 복잡한 UI 컴포넌트(모달, 링크 등)로 변환하는 JS 로직이 필요합니다.
const fieldValue = entity[field] !== undefined ? entity[field] : '';
html += `<td>${fieldValue}</td>`;
});
// 3. 작업 버튼 (index_actionButtons)
// 원본 코드를 완벽히 재현하려면 getListButton 로직을 JS로 구현해야 합니다.
html += '<td nowrap>';
<?php foreach ($viewDatas['index_actionButtons'] as $action => $label): ?>
// 버튼 HTML을 직접 삽입 (예: 상세 보기 버튼)
html += `<a href="/${apiEndpoint.split('/')[1]}/${entity.id || ''}/${action}" class="btn btn-sm btn-outline-secondary me-1"><?= $label ?></a>`;
<?php endforeach ?>
html += '</td>';
html += '</tr>';
});
tbody.innerHTML = html;
// 테이블 리사이즈 플러그인 재실행 (필요하다면)
// if (typeof $.fn.resizableTable === 'function') {
// $('.index_table').resizableTable();
// }
}
// 페이지 로드 시 데이터 호출 시작
fetchData();
// 필터링이나 페이지네이션 버튼 클릭 시 fetchData를 재호출하도록 연결해야 합니다.
// 예: document.getElementById('filter_search_button').addEventListener('click', fetchData);
});
</script>
<?= $this->endSection() ?>