dbmsv4 init...4
This commit is contained in:
parent
e767aa1450
commit
24d16ccdd6
@ -216,6 +216,7 @@ define('ICONS', [
|
|||||||
'SALE_UP' => '📈',
|
'SALE_UP' => '📈',
|
||||||
'SALE_DOWN' => '📉',
|
'SALE_DOWN' => '📉',
|
||||||
'SERVICE' => '🛎️',
|
'SERVICE' => '🛎️',
|
||||||
|
'CONSOLE' => '💻',
|
||||||
'SERVICE_ITEM' => 'SERVICE_ITEM',
|
'SERVICE_ITEM' => 'SERVICE_ITEM',
|
||||||
'SERVICE_ITEM_LINE' => 'SERVICE_ITEM_LINE',
|
'SERVICE_ITEM_LINE' => 'SERVICE_ITEM_LINE',
|
||||||
'SERVICE_ITEM_IP' => 'SERVICE_ITEM_IP',
|
'SERVICE_ITEM_IP' => 'SERVICE_ITEM_IP',
|
||||||
|
|||||||
@ -217,7 +217,7 @@ $routes->group('admin', ['namespace' => 'App\Controllers\Admin', 'filter' => 'au
|
|||||||
$routes->post('batchjob', 'ServerController::batchjob');
|
$routes->post('batchjob', 'ServerController::batchjob');
|
||||||
$routes->post('batchjob_delete', 'ServerController::batchjob_delete');
|
$routes->post('batchjob_delete', 'ServerController::batchjob_delete');
|
||||||
$routes->get('download/(:alpha)', 'ServerPartController::download/$1');
|
$routes->get('download/(:alpha)', 'ServerPartController::download/$1');
|
||||||
$routes->post('console/(:num)', 'ServerController::console/$1');
|
$routes->get('console/(:num)', 'ServerController::console/$1');
|
||||||
});
|
});
|
||||||
$routes->group('serverpart', function ($routes) {
|
$routes->group('serverpart', function ($routes) {
|
||||||
$routes->get('/', 'ServerPartController::index');
|
$routes->get('/', 'ServerPartController::index');
|
||||||
|
|||||||
@ -120,10 +120,10 @@ abstract class AbstractWebController extends Controller
|
|||||||
|
|
||||||
$viewDatas['layout'] = array_merge($layoutConfig, $viewDatas['layout']);
|
$viewDatas['layout'] = array_merge($layoutConfig, $viewDatas['layout']);
|
||||||
$view_path = $viewDatas['layout']['path'];
|
$view_path = $viewDatas['layout']['path'];
|
||||||
|
|
||||||
if ($template_path) {
|
if ($template_path) {
|
||||||
$view_path .= '/' . $template_path;
|
$view_path .= '/' . $template_path;
|
||||||
}
|
}
|
||||||
|
// dd($view_path);
|
||||||
//최종 ViewPath
|
//최종 ViewPath
|
||||||
$viewDatas['view_path'] = $view_path;
|
$viewDatas['view_path'] = $view_path;
|
||||||
helper([__FUNCTION__]);
|
helper([__FUNCTION__]);
|
||||||
|
|||||||
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Controllers\Admin\Equipment;
|
namespace App\Controllers\Admin\Equipment;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
use CodeIgniter\HTTP\RedirectResponse;
|
use CodeIgniter\HTTP\RedirectResponse;
|
||||||
use CodeIgniter\HTTP\RequestInterface;
|
use CodeIgniter\HTTP\RequestInterface;
|
||||||
use CodeIgniter\HTTP\ResponseInterface;
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use App\Entities\Equipment\ServerEntity;
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
class ServerController extends EquipmentController
|
class ServerController extends EquipmentController
|
||||||
{
|
{
|
||||||
@ -33,16 +34,25 @@ class ServerController extends EquipmentController
|
|||||||
return $this->action_render_process($action, $this->getViewDatas(), $this->request->getVar('ActionTemplate') ?? 'server');
|
return $this->action_render_process($action, $this->getViewDatas(), $this->request->getVar('ActionTemplate') ?? 'server');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function console(int $uid): string
|
protected function console_result_process(string $action): string
|
||||||
{
|
{
|
||||||
$entity = $this->service->getEntity($uid);
|
return $this->action_render_process($action, $this->getViewDatas(), $this->request->getVar('ActionTemplate') ?? 'server');
|
||||||
if (!$entity instanceof ServerEntity) {
|
}
|
||||||
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 오류발생: {$uid} 서버 정보를 찾을수 없습니다.");
|
public function console(int $uid): string|RedirectResponse
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!$uid) {
|
||||||
|
throw new RuntimeException(static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()}에 번호가 정의 되지 않았습니다.");
|
||||||
|
}
|
||||||
|
//View처리
|
||||||
|
$entity = $this->view_process($uid);
|
||||||
|
$action = __FUNCTION__;
|
||||||
|
//FormService에서 필요한 기존 데이터를 $entity에서 추출해서 넘김
|
||||||
|
$this->action_init_process($action, $entity->toArray());
|
||||||
|
$this->addViewDatas('entity', $entity);
|
||||||
|
return $this->console_result_process($action);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return $this->action_redirect_process('error', static::class . '->' . __FUNCTION__ . "에서 {$this->getTitle()} 상세보기 오류:" . $e->getMessage());
|
||||||
}
|
}
|
||||||
$viewDatas = [
|
|
||||||
'entity' => $entity,
|
|
||||||
'title' => $entity->getTitle(),
|
|
||||||
];
|
|
||||||
return view('admin/server/console', $viewDatas);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class ServerDTO extends CommonDTO
|
|||||||
public string $title = '';
|
public string $title = '';
|
||||||
public string $type = '';
|
public string $type = '';
|
||||||
public string $ip = '';
|
public string $ip = '';
|
||||||
public string $ilo_ip = '';
|
public string $viewer = '';
|
||||||
public string $os = '';
|
public string $os = '';
|
||||||
public int $price = 0;
|
public int $price = 0;
|
||||||
public string $manufactur_at = '';
|
public string $manufactur_at = '';
|
||||||
|
|||||||
@ -13,7 +13,7 @@ class ServerEntity extends EquipmentEntity
|
|||||||
'title' => '',
|
'title' => '',
|
||||||
'type' => '',
|
'type' => '',
|
||||||
'ip' => '',
|
'ip' => '',
|
||||||
'ilo_ip' => '',
|
'viewer' => '',
|
||||||
'os' => '',
|
'os' => '',
|
||||||
'price' => 0,
|
'price' => 0,
|
||||||
'manufactur_at' => '',
|
'manufactur_at' => '',
|
||||||
@ -57,9 +57,9 @@ class ServerEntity extends EquipmentEntity
|
|||||||
{
|
{
|
||||||
return $this->attributes['ip'] ?? '';
|
return $this->attributes['ip'] ?? '';
|
||||||
}
|
}
|
||||||
public function getIloIP(): string
|
public function getViewer(): string
|
||||||
{
|
{
|
||||||
return $this->attributes['ilo_ip'] ?? '';
|
return $this->attributes['viewer'] ?? '';
|
||||||
}
|
}
|
||||||
public function getOS(): string
|
public function getOS(): string
|
||||||
{
|
{
|
||||||
|
|||||||
@ -16,7 +16,7 @@ class ServerForm extends EquipmentForm
|
|||||||
"chassisinfo_uid",
|
"chassisinfo_uid",
|
||||||
"switchinfo_uid",
|
"switchinfo_uid",
|
||||||
"ip",
|
"ip",
|
||||||
"ilo_ip",
|
"viewer",
|
||||||
"title",
|
"title",
|
||||||
"os",
|
"os",
|
||||||
"price",
|
"price",
|
||||||
@ -29,12 +29,11 @@ class ServerForm extends EquipmentForm
|
|||||||
"chassisinfo_uid",
|
"chassisinfo_uid",
|
||||||
'switchinfo_uid',
|
'switchinfo_uid',
|
||||||
'ip',
|
'ip',
|
||||||
'ilo_ip',
|
|
||||||
'os',
|
'os',
|
||||||
"status",
|
"status",
|
||||||
];
|
];
|
||||||
$indexFilter = $filters;
|
$indexFilter = $filters;
|
||||||
$batchjobFilters = ['type', 'switchinfo_uid', 'ip', 'ilo_ip', 'os', 'status'];
|
$batchjobFilters = ['type', 'switchinfo_uid', 'ip', 'viewer', 'os', 'status'];
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
case 'create':
|
case 'create':
|
||||||
case 'create_form':
|
case 'create_form':
|
||||||
@ -53,7 +52,7 @@ class ServerForm extends EquipmentForm
|
|||||||
"type",
|
"type",
|
||||||
"switchinfo_uid",
|
"switchinfo_uid",
|
||||||
"ip",
|
"ip",
|
||||||
"ilo_ip",
|
"viewer",
|
||||||
"title",
|
"title",
|
||||||
"os",
|
"os",
|
||||||
"part",
|
"part",
|
||||||
@ -90,7 +89,6 @@ class ServerForm extends EquipmentForm
|
|||||||
$formRules[$field] = "required|trim|string";
|
$formRules[$field] = "required|trim|string";
|
||||||
break;
|
break;
|
||||||
case "ip": //ipv4 , ipv6 , both(ipv4,ipv6)
|
case "ip": //ipv4 , ipv6 , both(ipv4,ipv6)
|
||||||
case "ilo_ip": //ipv4 , ipv6 , both(ipv4,ipv6)
|
|
||||||
$formRules[$field] = sprintf("permit_empty|trim|valid_ip[both]%s", in_array($action, ["create", "create_form"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : "");
|
$formRules[$field] = sprintf("permit_empty|trim|valid_ip[both]%s", in_array($action, ["create", "create_form"]) ? "|is_unique[{$this->getAttribute('table')}.{$field}]" : "");
|
||||||
break;
|
break;
|
||||||
case "os":
|
case "os":
|
||||||
@ -114,7 +112,6 @@ class ServerForm extends EquipmentForm
|
|||||||
$entities = [];
|
$entities = [];
|
||||||
switch ($field) {
|
switch ($field) {
|
||||||
case 'ip':
|
case 'ip':
|
||||||
case 'ilo_ip':
|
|
||||||
if (in_array($action, ['create_form', 'modify_form'])) {
|
if (in_array($action, ['create_form', 'modify_form'])) {
|
||||||
if (array_key_exists($field, $formDatas)) {
|
if (array_key_exists($field, $formDatas)) {
|
||||||
$where = sprintf("status = '%s' OR %s='%s'", STATUS['AVAILABLE'], $field, $formDatas[$field]);
|
$where = sprintf("status = '%s' OR %s='%s'", STATUS['AVAILABLE'], $field, $formDatas[$field]);
|
||||||
@ -171,7 +168,6 @@ class ServerForm extends EquipmentForm
|
|||||||
// dd($options);
|
// dd($options);
|
||||||
break;
|
break;
|
||||||
case 'ip': //key=value이 같음주의
|
case 'ip': //key=value이 같음주의
|
||||||
case 'ilo_ip': //key=value이 같음주의
|
|
||||||
foreach ($this->getFormOption_process(service('part_ipservice'), $action, 'ip', $formDatas) as $tempEntity) {
|
foreach ($this->getFormOption_process(service('part_ipservice'), $action, 'ip', $formDatas) as $tempEntity) {
|
||||||
$tempOptions[$tempEntity->getTitle()] = $tempEntity->getTitle();
|
$tempOptions[$tempEntity->getTitle()] = $tempEntity->getTitle();
|
||||||
// $options['attributes'][$tempEntity->getPK()] = ['data-role' => implode(DEFAULTS['DELIMITER_ROLE'], $tempEntity->getRole())];
|
// $options['attributes'][$tempEntity->getPK()] = ['data-role' => implode(DEFAULTS['DELIMITER_ROLE'], $tempEntity->getRole())];
|
||||||
|
|||||||
@ -77,7 +77,6 @@ class ServerHelper extends EquipmentHelper
|
|||||||
switch ($field) {
|
switch ($field) {
|
||||||
case 'switchinfo_uid':
|
case 'switchinfo_uid':
|
||||||
case 'ip':
|
case 'ip':
|
||||||
case 'ilo_ip':
|
|
||||||
$extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' select-field' : 'select-field';
|
$extras['class'] = array_key_exists('class', $extras) ? $extras['class'] . ' select-field' : 'select-field';
|
||||||
$filter = parent::getListFilter($field, $value, $viewDatas, $extras);
|
$filter = parent::getListFilter($field, $value, $viewDatas, $extras);
|
||||||
break;
|
break;
|
||||||
@ -120,6 +119,19 @@ class ServerHelper extends EquipmentHelper
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case 'console':
|
||||||
|
$action = $label ? $label : form_label(
|
||||||
|
$label ? $label : ICONS['CONSOLE'],
|
||||||
|
$action,
|
||||||
|
[
|
||||||
|
"data-src" => "/admin/equipment/server/console/{$viewDatas['entity']->getPK()}",
|
||||||
|
"data-bs-toggle" => "modal",
|
||||||
|
"data-bs-target" => "#modal_action_form",
|
||||||
|
"class" => "btn btn-sm btn-primary form-label-sm",
|
||||||
|
...$extras
|
||||||
|
]
|
||||||
|
);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$action = parent::getListButton($action, $label, $viewDatas, $extras);
|
$action = parent::getListButton($action, $label, $viewDatas, $extras);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -51,128 +51,11 @@ class IconHelper
|
|||||||
*/
|
*/
|
||||||
private static function getIcons(): array
|
private static function getIcons(): array
|
||||||
{
|
{
|
||||||
return [
|
return ICONS;
|
||||||
'ADD' => '➕',
|
|
||||||
'LOGO' => '🖼️',
|
|
||||||
'EXCEL' => '📊',
|
|
||||||
'PDF' => '📄',
|
|
||||||
'GOOGLE' => '🌐',
|
|
||||||
'MEMBER' => '👤',
|
|
||||||
'LOGIN' => '🔑',
|
|
||||||
'LOGOUT' => '🚪',
|
|
||||||
'HOME' => '🏠',
|
|
||||||
'MENU' => '☰',
|
|
||||||
'NEW' => '🆕',
|
|
||||||
'REPLY' => '↩️',
|
|
||||||
'DATABASE' => '🗄️',
|
|
||||||
'DISLIKE' => '👎',
|
|
||||||
'LIKE' => '👍',
|
|
||||||
'DOWNLOAD' => '⬇️',
|
|
||||||
'UPLOAD' => '⬆️',
|
|
||||||
'COPY' => '📋',
|
|
||||||
'PASTE' => '📌',
|
|
||||||
'EDIT' => '✏️',
|
|
||||||
'VIEW' => '👁️',
|
|
||||||
'VIEW_OFF' => '🙈',
|
|
||||||
'PRINT' => '🖨️',
|
|
||||||
'SAVE' => '✔️',
|
|
||||||
'CANCEL' => '❌',
|
|
||||||
'CLOSE' => '✖️',
|
|
||||||
'CLIENT' => '👥',
|
|
||||||
'CHART' => '📈',
|
|
||||||
'CHECK' => '✔️',
|
|
||||||
'CHECK_OFF' => '⬜',
|
|
||||||
'CHECK_ON' => '☑️',
|
|
||||||
'CHECK_ALL' => '📑',
|
|
||||||
'CHECK_NONE' => '🚫',
|
|
||||||
'CHECK_SOME' => '➖',
|
|
||||||
'COUPON' => '🎟️',
|
|
||||||
'HISTORY' => '🕘',
|
|
||||||
'MODIFY' => '🔧',
|
|
||||||
'MODIFY_ALL' => '🛠️',
|
|
||||||
'BATCHJOB' => '⚙️',
|
|
||||||
'DELETE' => '🗑️',
|
|
||||||
'REBOOT' => '🔄',
|
|
||||||
'RELOAD' => '🔁',
|
|
||||||
'SETUP' => '⚙️',
|
|
||||||
'FLAG' => '🚩',
|
|
||||||
'SEARCH' => '🔍',
|
|
||||||
'PLAY' => '▶️',
|
|
||||||
'CART' => '🛒',
|
|
||||||
'CARD' => '💳',
|
|
||||||
'DEPOSIT' => '💰',
|
|
||||||
'DESKTOP' => '🖥️',
|
|
||||||
'DEVICE' => '📟',
|
|
||||||
'UP' => '⬆️',
|
|
||||||
'DOWN' => '⬇️',
|
|
||||||
'LEFT' => '⬅️',
|
|
||||||
'RIGHT' => '➡️',
|
|
||||||
'IMAGE_FILE' => '🖼️',
|
|
||||||
'CLOUD' => '☁️',
|
|
||||||
'SIGNPOST' => '📌',
|
|
||||||
'LOCK' => '🔒',
|
|
||||||
'UNLOCK' => '🔓',
|
|
||||||
'BOX' => '📦',
|
|
||||||
'BOXS' => '📦📦',
|
|
||||||
'ONETIME' => '⚡',
|
|
||||||
'MONTH' => '📅',
|
|
||||||
'EMAIL' => '✉️',
|
|
||||||
'MAIL' => '📧',
|
|
||||||
'PHONE' => '📞',
|
|
||||||
'POINT' => '⭐',
|
|
||||||
'ALRAM' => '🔔',
|
|
||||||
'PAYMENT' => '💸',
|
|
||||||
'LINK' => '🔗',
|
|
||||||
'SALE_UP' => '📈',
|
|
||||||
'SALE_DOWN' => '📉',
|
|
||||||
'SERVICE' => '🛎️',
|
|
||||||
'SERVICE_ITEM' => '<i class="bi bi-gear-wide-connected"></i>',
|
|
||||||
'SERVICE_ITEM_LINE' => '<i class="bi bi-chat-left-text"></i>',
|
|
||||||
'SERVICE_ITEM_IP' => '<i class="bi bi-globe"></i>',
|
|
||||||
'SERVICE_ITEM_SERVER' => '<i class="bi bi-server"></i>',
|
|
||||||
'SERVICE_ITEM_CPU' => '<i class="bi bi-cpu"></i>',
|
|
||||||
'SERVICE_ITEM_RAM' => '<i class="bi bi-memory"></i>',
|
|
||||||
'SERVICE_ITEM_STORAGE' => '<i class="bi bi-hdd-stack"></i>',
|
|
||||||
'SERVICE_ITEM_SOFTWARE' => '<i class="bi bi-box-seam"></i>',
|
|
||||||
'SERVICE_ITEM_DEFENCE' => '<i class="bi bi-shield-lock"></i>',
|
|
||||||
'SERVICE_ITEM_DOMAIN' => '<i class="bi bi-globe2"></i>',
|
|
||||||
'SERVICE_ITEM_OTHER' => '<i class="bi bi-gear-wide-connected"></i>',
|
|
||||||
'SERVER_ITEM_CPU' => '<i class="bi bi-cpu"></i>',
|
|
||||||
'SERVER_ITEM_RAM' => '<i class="bi bi-memory"></i>',
|
|
||||||
'SERVER_ITEM_DISK' => '<i class="bi bi-device-hdd"></i>',
|
|
||||||
'SERVER_ITEM_SWITCH' => '<i class="bi bi-diagram-3"></i>',
|
|
||||||
'SERVER_ITEM_OS' => '<i class="bi bi-microsoft"></i>',
|
|
||||||
'SERVER_ITEM_DB' => '<i class="bi bi-database"></i>',
|
|
||||||
'SERVER_ITEM_SOFTWARE' => '<i class="bi bi-window-sidebar"></i>',
|
|
||||||
'SERVER_ITEM_IP' => '<i class="bi bi-globe2"></i>',
|
|
||||||
'SERVER_ITEM_CS' => '<i class="bi bi-shield-check"></i>',
|
|
||||||
'SERVER_ITEM_ETC' => '<i class="bi bi-patch-question"></i>',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function getMessengerIcons(): array
|
private static function getMessengerIcons(): array
|
||||||
{
|
{
|
||||||
return [
|
return MESSENGER_ICONS;
|
||||||
'WHATSAPP' => '<i class="bi bi-whatsapp"></i>',
|
|
||||||
'VIBER' => '<i class="bi bi-viber"></i>',
|
|
||||||
'LINE' => '<i class="bi bi-chat-left-text"></i>',
|
|
||||||
'KAKAO' => '<i class="bi bi-chat-left-text"></i>',
|
|
||||||
'DISCORD' => '<i class="bi bi-discord"></i>',
|
|
||||||
'TELEGRAM' => '<i class="bi bi-telegram"></i>',
|
|
||||||
'SKYPE' => '<i class="bi bi-skype"></i>',
|
|
||||||
'YOUTUBE' => '<i class="bi bi-youtube"></i>',
|
|
||||||
'FACEBOOK' => '<i class="bi bi-facebook"></i>',
|
|
||||||
'TWITTER' => '<i class="bi bi-twitter"></i>',
|
|
||||||
'INSTAGRAM' => '<i class="bi bi-instagram"></i>',
|
|
||||||
'LINKEDIN' => '<i class="bi bi-linkedin"></i>',
|
|
||||||
'GITHUB' => '<i class="bi bi-github"></i>',
|
|
||||||
'GITLAB' => '<i class="bi bi-gitlab"></i>',
|
|
||||||
'BITBUCKET' => '<i class="bi bi-bitbucket"></i>',
|
|
||||||
'REDDIT' => '<i class="bi bi-reddit"></i>',
|
|
||||||
'TIKTOK' => '<i class="bi bi-tiktok"></i>',
|
|
||||||
'PINTEREST' => '<i class="bi bi-pinterest"></i>',
|
|
||||||
'TUMBLR' => '<i class="bi bi-tumblr"></i>',
|
|
||||||
'SNAPCHAT' => '<i class="bi bi-snapchat"></i>',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ return [
|
|||||||
'chassisinfo_uid' => "샷시명",
|
'chassisinfo_uid' => "샷시명",
|
||||||
'switchinfo_uid' => "스위치",
|
'switchinfo_uid' => "스위치",
|
||||||
'ip' => "IP",
|
'ip' => "IP",
|
||||||
'ilo_ip' => "ILO IP",
|
'viewer' => "Viewer",
|
||||||
'os' => "OS",
|
'os' => "OS",
|
||||||
'part' => "부품",
|
'part' => "부품",
|
||||||
'title' => "모델명",
|
'title' => "모델명",
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class ServerModel extends EquipmentModel
|
|||||||
"chassisinfo_uid",
|
"chassisinfo_uid",
|
||||||
"switchinfo_uid",
|
"switchinfo_uid",
|
||||||
"ip",
|
"ip",
|
||||||
"ilo_ip",
|
"viewer",
|
||||||
"os",
|
"os",
|
||||||
"title",
|
"title",
|
||||||
"price",
|
"price",
|
||||||
|
|||||||
@ -1,13 +1,231 @@
|
|||||||
<?= $this->extend($viewDatas['layout']['layout']) ?>
|
<?php
|
||||||
<?= $this->section('content') ?>
|
$viewerUrl = $viewDatas['entity']->getViewer() ?? '';
|
||||||
<?= session('message') ? $viewDatas['helper']->alertTrait(session('message')) : ""; ?>
|
$viewerUrl = trim((string) $viewerUrl);
|
||||||
|
|
||||||
|
// 개발 중 디버그 출력(원하면 false로)
|
||||||
|
$debug = true;
|
||||||
|
|
||||||
|
$isHls = $viewerUrl && preg_match('#\.m3u8(\?|$)#i', $viewerUrl);
|
||||||
|
|
||||||
|
// 정적 JS 경로 (네 프로젝트에 맞게 수정)
|
||||||
|
$ovenJs = '/js/ovenplayer.js';
|
||||||
|
$hlsJs = '/js/hls.min.js';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if ($debug): ?>
|
||||||
|
<div style="font-size:12px;color:#666;margin:6px 0;">
|
||||||
|
viewerUrl:
|
||||||
|
<?= esc($viewerUrl) ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* ====== 공통: 뷰어 영역이 항상 넓게 ====== */
|
||||||
|
.console-stage {
|
||||||
|
width: 100%;
|
||||||
|
height: 70vh;
|
||||||
|
/* 기본: 화면 높이의 70% */
|
||||||
|
min-height: 560px;
|
||||||
|
/* 최소 높이 */
|
||||||
|
background: #000;
|
||||||
|
border-radius: 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 모달 안에서 더 크게 쓰고 싶으면 높이를 좀 더 키움 */
|
||||||
|
.modal.show .console-stage {
|
||||||
|
height: 78vh;
|
||||||
|
min-height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iframe은 stage를 꽉 채우게 */
|
||||||
|
.console-frame {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ====== 핵심: 1280x800 원본 비율 유지하며 크게 (레터박스 허용) ======
|
||||||
|
- contain: 비율 유지 + 남는 공간 검정 여백
|
||||||
|
- cover: 꽉 채우기(일부 잘림)
|
||||||
|
*/
|
||||||
|
#ovenplayer-container video {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
object-fit: contain;
|
||||||
|
/* 여기만 cover로 바꾸면 꽉 채움 */
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 모달 내부 padding 때문에 작아지는 것 방지(가능하면 0) */
|
||||||
|
.modal-body {
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<div id="container" class="content">
|
<div id="container" class="content">
|
||||||
<div class="form_top"><?= $this->include("{$viewDatas['layout']['template']}/form_content_top"); ?></div>
|
<div class="mb-3">
|
||||||
<a href="https://<?= esc($viewDatas['entity']->getIloIP()) ?>" target="_blank">
|
<div class="d-flex align-items-center gap-2 flex-wrap">
|
||||||
Open iLO HTML5 Console
|
<?php if ($viewerUrl): ?>
|
||||||
</a>
|
<a class="btn btn-sm btn-primary" href="<?= esc($viewerUrl) ?>" target="_blank" rel="noopener">
|
||||||
<?php if (session('message')): ?>
|
새 창으로 열기
|
||||||
<div class="alert alert-danger text-start"><?= nl2br(session('message')) ?></div><?php endif; ?>
|
</a>
|
||||||
<div class="form_bottom"><?= $this->include("{$viewDatas['layout']['template']}/form_content_bottom"); ?></div>
|
<small class="text-muted">
|
||||||
|
(iframe이 차단되는 장비/콘솔은 새 창으로 열어주세요)
|
||||||
|
</small>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="alert alert-warning mb-0">
|
||||||
|
viewerUrl이 비어있습니다. (ServerEntity->viewer 확인)
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ($viewerUrl): ?>
|
||||||
|
|
||||||
|
<?php if ($isHls): ?>
|
||||||
|
<!-- HLS/LL-HLS: OvenPlayer -->
|
||||||
|
<div class="console-stage">
|
||||||
|
<div id="ovenplayer-container" style="width:100%;height:100%;"></div>
|
||||||
|
<div id="player-error" style="display:none;color:#fff;padding:12px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const url = <?= json_encode($viewerUrl, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>;
|
||||||
|
const OVEN_JS = <?= json_encode($ovenJs) ?>;
|
||||||
|
const HLS_JS = <?= json_encode($hlsJs) ?>;
|
||||||
|
|
||||||
|
let playerInstance = null;
|
||||||
|
let started = false;
|
||||||
|
|
||||||
|
function showError(msg) {
|
||||||
|
const err = document.getElementById('player-error');
|
||||||
|
const box = document.getElementById('ovenplayer-container');
|
||||||
|
if (box) box.style.display = 'none';
|
||||||
|
if (err) {
|
||||||
|
err.style.display = 'block';
|
||||||
|
err.textContent = msg;
|
||||||
|
}
|
||||||
|
console.error(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadScriptOnce(src, key) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const existing = document.querySelector(`script[data-${key}="1"]`);
|
||||||
|
if (existing) return resolve();
|
||||||
|
|
||||||
|
const s = document.createElement('script');
|
||||||
|
s.src = src;
|
||||||
|
s.async = true;
|
||||||
|
s.dataset[key] = "1";
|
||||||
|
s.onload = () => resolve();
|
||||||
|
s.onerror = () => reject(new Error(`Failed to load ${src}`));
|
||||||
|
document.head.appendChild(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ensureDeps() {
|
||||||
|
// hls.js 먼저 (Chrome/Edge는 필수)
|
||||||
|
if (typeof window.Hls === 'undefined') {
|
||||||
|
await loadScriptOnce(HLS_JS, 'hlsjs');
|
||||||
|
}
|
||||||
|
// OvenPlayer
|
||||||
|
if (typeof window.OvenPlayer === 'undefined') {
|
||||||
|
await loadScriptOnce(OVEN_JS, 'ovenplayer');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroyPlayerIfAny() {
|
||||||
|
try {
|
||||||
|
if (playerInstance && typeof playerInstance.remove === 'function') {
|
||||||
|
playerInstance.remove();
|
||||||
|
}
|
||||||
|
} catch (e) { }
|
||||||
|
playerInstance = null;
|
||||||
|
|
||||||
|
// 컨테이너 초기화
|
||||||
|
const box = document.getElementById('ovenplayer-container');
|
||||||
|
if (box) box.innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function startPlayer() {
|
||||||
|
if (started) return;
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
if (typeof window.OvenPlayer === 'undefined') {
|
||||||
|
showError('OvenPlayer 로드 실패(ovenplayer.js 경로 확인)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeof window.Hls === 'undefined') {
|
||||||
|
showError('hls.js 로드 실패(hls.min.js 경로 확인)');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroyPlayerIfAny();
|
||||||
|
|
||||||
|
// LL-HLS(fMP4) 안정 옵션 + credentials 강제 off
|
||||||
|
playerInstance = window.OvenPlayer.create('ovenplayer-container', {
|
||||||
|
autoStart: true,
|
||||||
|
autoFallback: true,
|
||||||
|
mute: false,
|
||||||
|
sources: [{ type: 'hls', file: url }],
|
||||||
|
hlsConfig: {
|
||||||
|
lowLatencyMode: true,
|
||||||
|
backBufferLength: 0,
|
||||||
|
liveSyncDurationCount: 1,
|
||||||
|
liveMaxLatencyDurationCount: 3,
|
||||||
|
xhrSetup: function (xhr) { xhr.withCredentials = false; }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function boot() {
|
||||||
|
try {
|
||||||
|
await ensureDeps();
|
||||||
|
|
||||||
|
// ===== Bootstrap modal 안에서 “작게” 뜨는 문제 해결 =====
|
||||||
|
// 모달이 완전히 열린(shown) 다음에 플레이어 생성
|
||||||
|
const container = document.getElementById('ovenplayer-container');
|
||||||
|
const modal = container ? container.closest('.modal') : null;
|
||||||
|
|
||||||
|
if (modal) {
|
||||||
|
// 이미 열린 모달이라면 약간 딜레이 후 시작
|
||||||
|
if (modal.classList.contains('show')) {
|
||||||
|
setTimeout(startPlayer, 80);
|
||||||
|
} else {
|
||||||
|
modal.addEventListener('shown.bs.modal', function () {
|
||||||
|
started = false; // 다시 열릴 때 재생성 가능하게
|
||||||
|
setTimeout(startPlayer, 80);
|
||||||
|
}, { once: true });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 모달이 아니면 바로 시작
|
||||||
|
setTimeout(startPlayer, 30);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showError(e.message || String(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boot();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php else: ?>
|
||||||
|
<!-- iLO/noVNC/Proxmox 콘솔/텍스트 콘솔: iframe embed -->
|
||||||
|
<div class="console-stage">
|
||||||
|
<iframe class="console-frame" src="<?= esc($viewerUrl) ?>" allow="clipboard-read; clipboard-write; fullscreen"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-pointer-lock allow-top-navigation-by-user-activation">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-2 text-muted" style="font-size:12px;">
|
||||||
|
※ iLO/일부 콘솔은 보안 헤더로 iframe 표시가 막힐 수 있습니다. 그 경우 위의 “새 창으로 열기”를 사용하세요.
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<?= $this->endSection() ?>
|
|
||||||
@ -10,19 +10,33 @@
|
|||||||
<th style=" width: 250px">
|
<th style=" width: 250px">
|
||||||
<?= $serverCellDatas['serverPartHelper']->getListButton('CPU', 'CPU', ['serverinfo_uid' => $entity->getPK()]) ?>
|
<?= $serverCellDatas['serverPartHelper']->getListButton('CPU', 'CPU', ['serverinfo_uid' => $entity->getPK()]) ?>
|
||||||
/ <?= $serverCellDatas['serverPartHelper']->getListButton('RAM', 'RAM', ['serverinfo_uid' => $entity->getPK()]) ?>
|
/ <?= $serverCellDatas['serverPartHelper']->getListButton('RAM', 'RAM', ['serverinfo_uid' => $entity->getPK()]) ?>
|
||||||
/ <?= $serverCellDatas['serverPartHelper']->getListButton('DISK', 'DISK', ['serverinfo_uid' => $entity->getPK()]) ?>
|
/
|
||||||
|
<?= $serverCellDatas['serverPartHelper']->getListButton('DISK', 'DISK', ['serverinfo_uid' => $entity->getPK()]) ?>
|
||||||
|
</th>
|
||||||
|
<th style="width: 200px">
|
||||||
|
<?= $serverCellDatas['serverPartHelper']->getListButton('IP', '추가IP', ['serverinfo_uid' => $entity->getPK()]) ?>
|
||||||
|
</th>
|
||||||
|
<th style="width: 200px">
|
||||||
|
<?= $serverCellDatas['serverPartHelper']->getListButton('CS', 'CS', ['serverinfo_uid' => $entity->getPK()]) ?>
|
||||||
|
</th>
|
||||||
|
<th style="width: 200px">
|
||||||
|
<?= $serverCellDatas['serverPartHelper']->getListButton('SOFTWARE', 'SOFTWARE', ['serverinfo_uid' => $entity->getPK()]) ?>
|
||||||
</th>
|
</th>
|
||||||
<th style="width: 200px"><?= $serverCellDatas['serverPartHelper']->getListButton('IP', '추가IP', ['serverinfo_uid' => $entity->getPK()]) ?></th>
|
|
||||||
<th style="width: 200px"><?= $serverCellDatas['serverPartHelper']->getListButton('CS', 'CS', ['serverinfo_uid' => $entity->getPK()]) ?></th>
|
|
||||||
<th style="width: 200px"><?= $serverCellDatas['serverPartHelper']->getListButton('SOFTWARE', 'SOFTWARE', ['serverinfo_uid' => $entity->getPK()]) ?></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="text-center">
|
<tr class="text-center">
|
||||||
<td nowrap>
|
<td nowrap>
|
||||||
<div><?= $serverCellDatas['helper']->getFieldView('switchinfo_uid', $entity->getSwitchInfoUid(), $serverCellDatas) ?></div>
|
<div>
|
||||||
|
<?= $serverCellDatas['helper']->getFieldView('switchinfo_uid', $entity->getSwitchInfoUid(), $serverCellDatas) ?>
|
||||||
|
</div>
|
||||||
<div><?= $entity->getTitle() ?></div>
|
<div><?= $entity->getTitle() ?></div>
|
||||||
<div><?= $entity->getIP() ?></div>
|
<div><?= $entity->getIP() ?></div>
|
||||||
<div><?= $entity->getOS() ?></div>
|
<div><?= $entity->getOS() ?></div>
|
||||||
<div>금액 : <span class="text-danger"><?= number_format($entity->getPrice()) ?></span>원</div>
|
<div>금액 : <span class="text-danger"><?= number_format($entity->getPrice()) ?></span>원</div>
|
||||||
|
<?php if ($serverCellDatas['entity']->getViewer()): ?>
|
||||||
|
<div>
|
||||||
|
<?= $serverCellDatas['helper']->getListButton('console', "", $serverCellDatas) ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<?= view_cell("\App\Cells\Equipment\ServerPartCell::parttable", [
|
<?= view_cell("\App\Cells\Equipment\ServerPartCell::parttable", [
|
||||||
'serverinfo_uid' => $entity->getPK(),
|
'serverinfo_uid' => $entity->getPK(),
|
||||||
|
|||||||
2
public/js/hls.min.js
vendored
Normal file
2
public/js/hls.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
public/js/ovenplayer.js
Normal file
2
public/js/ovenplayer.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user