Files
portal-api/resources/views/admin/customer/console.blade.php
T
2025-07-29 10:24:14 +07:00

274 lines
11 KiB
PHP

@extends('admin.main')
@push('style')
<link rel="stylesheet" href="{{ asset('lib/wmks/css/wmks-all.css') }}" />
<link rel="stylesheet" href="{{ asset('lib/adminlte/adminlte.css') }}">
<link rel="stylesheet" href="{{ asset('css/service/console.css') }}">
@endpush
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-12">
<!-- Header -->
<div class="card">
<div class="card-header">
<h3 class="card-title">VMware Console</h3>
<div class="card-tools">
<a href="{{ route('customer.product', ['userid' => $userid ?? 0, 'product' => $product->id ?? 0, 'type' => $type ?? 4]) }}"
class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> Quay lại
</a>
</div>
</div>
<div class="card-body">
<p class="mb-0"><strong>VM:</strong> {{ $product->name ?? 'VM Console' }}</p>
</div>
</div>
<!-- Control Panel -->
<div class="card">
<div class="card-header">
<h5 class="card-title">Điều khiển Console</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="sendStringText">Nhập văn bản:</label>
<input id="sendStringText" class="form-control" type="text"
placeholder="Nhập văn bản...">
</div>
<div class="col-md-6 mb-3">
<label>&nbsp;</label>
<div class="btn-group d-flex" role="group">
<button onclick="enterFullScreen()" class="btn btn-primary flex-fill">
<i class="fas fa-expand"></i> Toàn màn hình
</button>
<button onclick="sendCAD()" class="btn btn-success flex-fill">
<i class="fas fa-keyboard"></i> Ctrl+Alt+Del
</button>
<button onclick="sendInputString()" class="btn btn-info flex-fill">
<i class="fas fa-paper-plane"></i> Gửi văn bản
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Console Container -->
<div class="card">
<div class="card-body p-0 position-relative">
<!-- Loading State -->
<div id="loadingState"
class="loading-container d-flex align-items-center justify-content-center text-black fade-transition"
style="height: 70vh;">
<div class="text-center">
<!-- Modern Spinner -->
<div class="spinner-box">
<div class="three-quarter-spinner"></div>
</div>
<!-- Loading Text -->
<h4 class="mb-3 font-weight-bold">{{ __('Đang kết nối đến vCenter') }}</h4>
<p class="mb-4 text-light" id="loadingText">{{ __('Khởi tạo kết nối Console') }}
</p>
<!-- Loading Dots Animation -->
<div class="loading-dots justify-content-center">
<span></span>
<span></span>
<span></span>
</div>
<!-- Connection Status -->
<div class="mt-4">
<small class="text-dark opacity-75"
id="connectionStatus">{{ __('Đang thiết lập phiên làm việc...') }}</small>
</div>
</div>
</div>
<!-- Console Display -->
<div id="wmksContainer"
class="console-container d-flex justify-content-center align-items-center bg-dark fade-transition"
style="height: 70vh; opacity: 0; position: absolute; top: 0; left: 0; right: 0;">
</div>
</div>
</div>
</div>
</div>
</div>
<script src="{{ asset('lib/jquery/jquery.min.js') }}"></script>
<script src="{{ asset('lib/jquery-ui/jquery-ui.min.js') }}"></script>
<script src="{{ asset('lib/wmks/wmks.min.js') }}"></script>
<script src="{{ asset('lib/wmks/wmks-sdk-example.js') }}"></script>
<script type="text/javascript">
// Loading management variables
let loadingSteps = [
'{{ __('Khởi tạo kết nối...') }}',
'{{ __('Đang xác thực...') }}',
'{{ __('Thiết lập phiên làm việc...') }}',
'{{ __('Đang kết nối Console...') }}',
'{{ __('Sẵn sàng!') }}'
];
let currentStep = 0;
// Initialize loading state
$(document).ready(function() {
showLoadingState();
animateLoadingText();
});
// Show loading state with smooth animation
function showLoadingState() {
$('#loadingState').css('opacity', '1').show();
$('#wmksContainer').css('opacity', '0').hide();
}
// Hide loading state and show console
function hideLoadingAndShowConsole() {
$('#loadingText').text('{{ __('Kết nối thành công!') }}');
$('#connectionStatus').text('{{ __('Console đã sẵn sàng') }}');
setTimeout(() => {
$('#loadingState').animate({
opacity: 0
}, 400, function() {
$(this).hide();
$('#wmksContainer').show().animate({
opacity: 1
}, 400);
});
}, 800);
}
// Show error state
function showErrorState(errorMessage) {
$('#loadingState').animate({
opacity: 0
}, 300, function() {
$(this).hide();
$('#wmksContainer').html(`
<div class="d-flex align-items-center justify-content-center w-100 h-100">
<div class="text-center text-black">
<div class="mb-3">
<i class="fas fa-exclamation-triangle text-danger" style="font-size: 3rem;"></i>
</div>
<h5>{{ __('Kết nối thất bại') }}</h5>
<p class="text-muted">${errorMessage || '{{ __('Máy chủ không sẵn sàng hoặc có lỗi kết nối') }}'}</p>
<button onclick="location.reload()" class="btn btn-primary">
<i class="fas fa-redo"></i> {{ __('Thử lại') }}
</button>
</div>
</div>
`).show().animate({
opacity: 1
}, 400);
});
}
// Animate loading text through steps
function animateLoadingText() {
setInterval(() => {
if (currentStep < loadingSteps.length - 1) {
currentStep++;
$('#loadingText').fadeOut(200, function() {
$(this).text(loadingSteps[currentStep]).fadeIn(200);
});
}
}, 1500);
}
// Update connection status
function updateConnectionStatus(status) {
$('#connectionStatus').fadeOut(200, function() {
$(this).text(status).fadeIn(200);
});
}
let WMKSContainer = $('#wmksContainer');
var wmks = WMKS.createWMKS("wmksContainer", {})
.register(WMKS.CONST.Events.CONNECTION_STATE_CHANGE, function(event, data) {
if (data.state === WMKS.CONST.ConnectionState.CONNECTED) {
console.log("connection state change : connected");
// Hide loading when WMKS successfully connects
hideLoadingAndShowConsole();
}
});
const getTicket = new Promise((resolve, reject) => {
updateConnectionStatus('{{ __('Đang lấy ticket xác thực...') }}');
$.ajax({
url: '{{ route('api.GetConsoleTicket') }}',
type: 'get',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'Accept': 'application/json',
'Authorization': 'Bearer {{ request()->cookie('accessToken') }}'
},
data: {
product: {{ $product->id ?? 0 }}
},
success: function(response) {
if (response.error === false) {
updateConnectionStatus('{{ __('Đang thiết lập kết nối Console...') }}');
resolve(response);
} else {
reject(response.message);
}
},
error: function(xhr, status, error) {
reject(`{{ __('Lỗi kết nối:') }} ${error}`);
}
});
});
getTicket
.then(result => {
if (result !== false) {
updateConnectionStatus('{{ __('Đang kết nối đến Console...') }}');
const wmksHost = '{{ config('vmware.wmks_host', '10.10.10.120') }}';
wmks.connect(`wss://${wmksHost}/ticket/${result.data}`);
}
})
.catch(error => {
console.log(`Có lỗi xảy ra: ${error}.`);
showErrorState(error);
});
// Console control functions
function enterFullScreen() {
if (wmks && wmks.canFullScreen()) {
wmks.enterFullScreen();
}
}
function sendCAD() {
if (wmks) {
wmks.sendCAD();
}
}
function sendInputString() {
const inputText = $('#sendStringText').val().trim();
if (inputText && wmks) {
wmks.sendInputString(inputText);
$('#sendStringText').val('');
} else if (!inputText) {
alert('{{ __('Vui lòng nhập văn bản cần gửi') }}');
}
}
// Enter key support for input field
$('#sendStringText').on('keypress', function(e) {
if (e.which == 13) {
sendInputString();
}
});
</script>
@endsection