strong all

This commit is contained in:
2026-01-19 21:14:58 +08:00
parent 5364edfc46
commit 1129376981
10 changed files with 5827 additions and 2090 deletions

View File

@@ -113,6 +113,30 @@
/* 分页 */
.pagination { display: flex; align-items: center; justify-content: flex-end; padding: 15px; gap: 10px; }
.pagination button { background: #fff; border: 1px solid #d9d9d9; padding: 5px 10px; border-radius: 4px; cursor: pointer; }
/* === New Interactive Elements === */
/* Modal */
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: none; justify-content: center; align-items: center; z-index: 1000; }
.modal-content { background: #fff; width: 500px; padding: 20px; border-radius: 4px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: fadeIn 0.3s; }
.modal-header { font-size: 16px; font-weight: bold; margin-bottom: 15px; border-bottom: 1px solid #eee; padding-bottom: 10px; display: flex; justify-content: space-between; }
/* Drawer (Right Panel) */
.drawer-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.2); z-index: 900; display: none; }
.drawer { position: fixed; top: 0; right: -450px; width: 450px; height: 100%; background: #fff; box-shadow: -2px 0 8px rgba(0,0,0,0.1); transition: right 0.3s ease; z-index: 901; display: flex; flex-direction: column; }
.drawer.open { right: 0; }
.drawer-header { padding: 20px; border-bottom: 1px solid #eee; background: #fafafa; display: flex; justify-content: space-between; align-items: center; }
.drawer-body { padding: 20px; flex: 1; overflow-y: auto; }
/* Toast Notification */
.toast { position: fixed; top: 20px; left: 50%; transform: translateX(-50%); background: #333; color: #fff; padding: 10px 20px; border-radius: 4px; z-index: 2000; display: none; opacity: 0; transition: opacity 0.3s; }
.toast.show { display: block; opacity: 1; }
/* Form Styles */
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; color: #666; font-weight: 500; }
.form-input { width: 100%; padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px; box-sizing: border-box; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
</style>
</head>
<body>
@@ -137,10 +161,10 @@
<div class="sidebar">
<h3>资源列表</h3>
<ul>
<li><a href="#" class="active">全部实例 (14)</a></li>
<li><a href="#">运行中 (10)</a></li>
<li><a href="#">已停止 (3)</a></li>
<li><a href="#">异常/维护 (1)</a></li>
<li><a href="javascript:void(0)" class="active" onclick="filterByStatus('all', this)">全部实例 (14)</a></li>
<li><a href="javascript:void(0)" onclick="filterByStatus('running', this)">运行中 (10)</a></li>
<li><a href="javascript:void(0)" onclick="filterByStatus('stopped', this)">已停止 (3)</a></li>
<li><a href="javascript:void(0)" onclick="filterByStatus('maintenance', this)">异常/维护 (1)</a></li>
</ul>
<h3>配额监控</h3>
@@ -169,7 +193,7 @@
<form class="search-bar">
<fieldset>
<label>关键词:</label> <input type="text" placeholder="Instance ID / Name">
<label>关键词:</label> <input type="text" id="searchInput" placeholder="Instance ID / Name">
<label>标签:</label> <input type="text" placeholder="Key:Value">
<label>付费类型:</label>
<select>
@@ -178,17 +202,18 @@
<option>按量付费</option>
<option>抢占式实例</option>
</select>
<button type="button" class="btn-primary" onclick="alert('Searching...')">刷新列表</button>
<button type="button">重置</button>
<button type="button" class="btn-primary" onclick="searchInstances()">刷新列表</button>
<button type="button" onclick="resetSearch()">重置</button>
</fieldset>
</form>
<div class="toolbar">
<button>启动</button>
<button>停止</button>
<button>重启</button>
<button>释放设置</button>
<button>修改计费模式</button>
<button style="background: var(--primary); color: #fff; border-color: var(--primary);" onclick="openCreateModal()">+ 创建实例</button>
<button onclick="performToolbarAction('start')">启动</button>
<button onclick="performToolbarAction('stop')">停止</button>
<button onclick="performToolbarAction('restart')">重启</button>
<button onclick="showToast('功能开发中: 修改释放设置', 'warning')">释放设置</button>
<button onclick="showToast('功能开发中: 修改计费模式', 'warning')">修改计费模式</button>
</div>
<div class="instance-list">
@@ -221,11 +246,11 @@
<span class="status-running">运行中</span>
</div>
<div class="action-group">
<button>远程连接</button>
<button>监控</button>
<button>更多...</button>
<button class="btn-danger" onclick="confirmDelete()">强制停止</button>
<button class="btn-danger" onclick="confirmDelete()">彻底销毁</button>
<button onclick="remoteConnect('i-bp1j2k3l4m5n')">远程连接</button>
<button onclick="openMonitor('i-bp1j2k3l4m5n')">监控</button>
<button onclick="showMoreMenu(this)">更多...</button>
<button class="btn-danger" onclick="confirmDelete('i-bp1j2k3l4m5n')">强制停止</button>
<button class="btn-danger" onclick="confirmDelete('i-bp1j2k3l4m5n', true)">彻底销毁</button>
</div>
</div>
@@ -275,8 +300,8 @@
<span>未开通</span>
</div>
<div class="action-group">
<button style="color: #fa8c16; font-weight:bold;">立即开通</button>
<button>了解详情</button>
<button style="color: #fa8c16; font-weight:bold;" onclick="openProductIntro('scaling')">立即开通</button>
<button onclick="openProductIntro('scaling_doc')">了解详情</button>
</div>
</div>
@@ -404,7 +429,7 @@
</div>
<div style="grid-column: 1 / -1; margin-top: 5px;">
<p>请及时充值,以免影响实例的正常运行。</p>
<button style="background: #f5222d; color: white; border: none; padding: 4px 12px; border-radius: 2px;">立即充值</button>
<button onclick="openRecharge()" style="background: #f5222d; color: white; border: none; padding: 4px 12px; border-radius: 2px;">立即充值</button>
</div>
</div>
@@ -438,10 +463,10 @@
</div>
<div class="pagination">
<button>&lt; 上一页</button>
<span>第 1 / 5 页</span>
<button>下一页 &gt;</button>
<select>
<button onclick="changePage(-1)">&lt; 上一页</button>
<span id="pageInfo">第 1 / 5 页</span>
<button onclick="changePage(1)">下一页 &gt;</button>
<select onchange="changePageSize(this)">
<option>每页 10 条</option>
<option>每页 20 条</option>
<option>每页 50 条</option>
@@ -457,9 +482,159 @@
</div>
<!-- Components -->
<!-- Create Instance Modal -->
<div id="createModal" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">
<span>创建新实例 (ECI)</span>
<span onclick="closeCreateModal()" style="cursor:pointer; color:#999;"></span>
</div>
<div class="form-group">
<label>实例名称</label>
<input type="text" id="newInstanceName" class="form-input" placeholder="例如: Web-Server-02">
</div>
<div class="form-group">
<label>镜像</label>
<select id="newInstanceImage" class="form-input">
<option value="Ubuntu 22.04 LTS">Ubuntu 22.04 LTS</option>
<option value="CentOS 7.9">CentOS 7.9</option>
<option value="Aliyun Linux 3">Aliyun Linux 3</option>
<option value="Windows Server 2022">Windows Server 2022</option>
</select>
</div>
<div class="form-group">
<label>规格</label>
<select id="newInstanceType" class="form-input">
<option value="2 vCPU / 4 GiB">ecs.t6-c1m2.large (2 vCPU / 4 GiB)</option>
<option value="4 vCPU / 8 GiB">ecs.c7.xlarge (4 vCPU / 8 GiB)</option>
<option value="8 vCPU / 16 GiB">ecs.g7.2xlarge (8 vCPU / 16 GiB)</option>
</select>
</div>
<div style="text-align: right; margin-top: 20px;">
<button onclick="closeCreateModal()" style="margin-right: 10px; padding: 6px 15px; border: 1px solid #d9d9d9; background: #fff; cursor: pointer; border-radius: 4px;">取消</button>
<button onclick="confirmCreate()" style="padding: 6px 15px; background: var(--primary); color: #fff; border: none; cursor: pointer; border-radius: 4px;">立即购买</button>
</div>
</div>
</div>
<!-- Instance Detail Drawer -->
<div id="drawerOverlay" class="drawer-overlay" onclick="closeDrawer()"></div>
<div id="detailDrawer" class="drawer">
<div class="drawer-header">
<h3 id="drawerTitle">Instance Details</h3>
<button onclick="closeDrawer()" style="border:none; background:none; cursor:pointer; font-size:16px;"></button>
</div>
<div class="drawer-body">
<div style="background: #f5f5f5; padding: 15px; border-radius: 4px; margin-bottom: 20px;">
<p><strong>Status:</strong> <span style="color:green">Running</span></p>
<p><strong>Region:</strong> CN-East-2 (Zone B)</p>
<p><strong>Public IP:</strong> 139.196.128.44</p>
<p><strong>Private IP:</strong> 192.168.1.101</p>
</div>
<h4>监控概览 (1 Hour)</h4>
<div style="height: 100px; background: #fafafa; border: 1px solid #eee; display: flex; align-items: flex-end; padding: 10px; gap: 5px;">
<!-- Fake Chart Bars -->
<div style="width: 10%; height: 30%; background: #badde8;"></div>
<div style="width: 10%; height: 50%; background: #badde8;"></div>
<div style="width: 10%; height: 80%; background: #108ee9;"></div>
<div style="width: 10%; height: 60%; background: #badde8;"></div>
<div style="width: 10%; height: 40%; background: #badde8;"></div>
<div style="width: 10%; height: 90%; background: #f04134;"></div>
<div style="width: 10%; height: 50%; background: #badde8;"></div>
<div style="width: 10%; height: 30%; background: #badde8;"></div>
</div>
<h4 style="margin-top:20px;">配置信息</h4>
<ul style="line-height:2; color:#666;">
<li>Instance Type: ecs.g7.xlarge</li>
<li>Image ID: ubuntu_22_04_x64_20G_alibase</li>
<li>Security Group: sg-bp12345678</li>
<li>VPC ID: vpc-bp1abcdefg</li>
</ul>
</div>
</div>
<div id="toast" class="toast">Action Successful</div>
<script>
// 脚本逻辑:处理全选和危险操作确认
// --- State Management ---
// Toast
function showToast(msg) {
const t = document.getElementById('toast');
t.innerText = msg;
t.classList.add('show');
setTimeout(() => t.classList.remove('show'), 3000);
}
// Modal Logic
function openCreateModal() {
document.getElementById('createModal').style.display = 'flex';
}
function closeCreateModal() {
document.getElementById('createModal').style.display = 'none';
document.getElementById('newInstanceName').value = '';
}
function confirmCreate() {
showToast('订单已提交,实例正在初始化...');
closeCreateModal();
// Here we could simulate adding a row, but for static demo toast is enough
setTimeout(() => {
// Simulate "Created" by navigating or refreshing? No, just an alert.
// Ideally we add a row to DOM
addInstanceRow();
}, 1000);
}
function addInstanceRow() {
const name = document.getElementById('newInstanceName').value || 'New-Instance-' + Math.floor(Math.random()*1000);
const list = document.querySelector('.instance-list');
const newRow = document.createElement('div');
newRow.className = 'list-row';
newRow.innerHTML = `
<div><input type="checkbox" class="row-checkbox"></div>
<div>
<strong onclick="openDrawer('${name}')">${name}</strong><br>
<small>镜像: Ubuntu 22.04</small>
</div>
<div><span>Checking...</span><br><span style="color:#999">192.168.1.${Math.floor(Math.random()*255)}</span></div>
<div><span>2 vCPU</span><br><span>4 GiB</span></div>
<div><span class="status-running" style="color:#fa8c16">启动中...</span></div>
<div class="action-group">
<button>管理</button>
</div>
`;
// Insert after header
list.insertBefore(newRow, list.children[1]);
}
// Drawer Logic
function openDrawer(name) {
document.getElementById('drawerTitle').innerText = name || 'Instance Details';
document.getElementById('drawerOverlay').style.display = 'block';
setTimeout(() => document.getElementById('detailDrawer').classList.add('open'), 10);
}
function closeDrawer() {
document.getElementById('detailDrawer').classList.remove('open');
setTimeout(() => document.getElementById('drawerOverlay').style.display = 'none', 300);
}
// Bind click events for all existing instance names
document.querySelectorAll('.list-row strong').forEach(el => {
// Remove old onclick
el.removeAttribute('onclick');
el.addEventListener('click', function() {
// Get name text
const name = this.innerText.split('(')[0].trim() || 'Instance';
openDrawer(name);
});
});
// Toolbar Actions
// 全选/取消全选
document.getElementById('selectAll').addEventListener('change', function(e) {
const checkboxes = document.querySelectorAll('.row-checkbox');
@@ -468,15 +643,174 @@
});
});
function performAction(action) {
// Get selected
const checkboxes = document.querySelectorAll('.row-checkbox:checked');
if (checkboxes.length === 0) {
alert('请先选择至少一个实例');
return;
}
const count = checkboxes.length;
if(confirm(`确定要对选中的 ${count} 台实例执行 [${action.toUpperCase()}] 操作吗?`)) {
showToast(`指令已下发: ${action.toUpperCase()} ${count} instances`);
// Reset selection
checkboxes.forEach(c => c.checked = false);
document.getElementById('selectAll').checked = false;
}
}
// 危险操作二次确认
function confirmDelete() {
const userInput = prompt("这是一个高风险操作!\n请输入 'DELETE' 以确认销毁该实例:");
if (userInput === 'DELETE') {
alert('操作已提交:实例正在销毁中...');
} else {
alert('操作已取消。');
showToast('操作已提交:实例正在销毁中...');
}
}
// -------------------------------------------------------------------------
// Enhanced Interactivity (New)
// -------------------------------------------------------------------------
// 1. Sidebar Filter
function filterByStatus(status, el) {
// Update URL hash for simulation
window.location.hash = status;
// Active state
document.querySelectorAll('.sidebar li a').forEach(a => a.classList.remove('active'));
if(el) el.classList.add('active');
const rows = document.querySelectorAll('.list-row:not(.ad-row):not(.billing-alert-row)');
rows.forEach(row => {
const statusText = row.querySelector('div:nth-child(5)').innerText.trim();
let show = false;
if (status === 'all') show = true;
else if (status === 'running' && (statusText.includes('运行中') || statusText.includes('启动中'))) show = true;
else if (status === 'stopped' && statusText.includes('已停止')) show = true;
else if (status === 'maintenance' && statusText.includes('维护')) show = true;
row.style.display = show ? 'grid' : 'none';
});
showToast(`已筛选: ${el ? el.innerText : status}`);
}
// 2. Toolbar Logic (Renamed to avoid conflict)
function performToolbarAction(action) {
// Re-use existing logic, just better naming
const checkboxes = document.querySelectorAll('.row-checkbox:checked');
if (checkboxes.length === 0) {
alert('请先勾选需要操作的实例');
return;
}
showToast(`正在对 ${checkboxes.length} 台实例执行 [${action}]...`);
setTimeout(() => {
showToast('操作指令已下发');
checkboxes.forEach(c => c.checked = false);
document.getElementById('selectAll').checked = false;
}, 800);
}
// 3. Row Actions
function remoteConnect(instanceId) {
const width = 800;
const height = 600;
const left = (screen.width - width) / 2;
const top = (screen.height - height) / 2;
// Open a fake terminal window
const win = window.open("", "_blank", `width=${width},height=${height},top=${top},left=${left}`);
win.document.write(`
<body style="background:#000; color:#0f0; font-family:monospace; padding:20px;">
<p>Connecting to ${instanceId}...</p>
<p>Authenticating...</p>
<p>Welcome to Ubuntu 22.04 LTS</p>
<p>root@${instanceId}:~# <span id="cursor">_</span></p>
<script>
setInterval(() => {
const c = document.getElementById('cursor');
c.style.visibility = c.style.visibility === 'hidden' ? 'visible' : 'hidden';
}, 500);
<\/script>
</body>
`);
}
function openMonitor(instanceId) {
openDrawer(instanceId + ' - 实时监控');
}
function showMoreMenu(btn) {
// Simple fallback
const actions = ['创建快照', '变更配置', '重置密码', '更换操作系统'];
const action = prompt(`[${actions.join(' | ')}]\n请输入要执行的操作:`, actions[0]);
if(action) {
showToast(`正在执行: ${action}`);
}
}
// 4. Search Bar
function searchInstances() {
const val = document.getElementById('searchInput').value;
if(!val) {
// refresh
showToast('刷新列表成功');
// reset filters
filterByStatus('all', document.querySelector('.sidebar a.active'));
} else {
showToast(`正在搜索 "${val}"...`);
}
}
function resetSearch() {
document.getElementById('searchInput').value = '';
// Trigger input event to clear filter
document.getElementById('searchInput').dispatchEvent(new Event('input'));
showToast('搜索条件已重置');
}
// 5. Pagination
let currentPage = 1;
function changePage(dir) {
const newPage = currentPage + dir;
if(newPage < 1 || newPage > 5) return;
currentPage = newPage;
document.getElementById('pageInfo').innerText = `${currentPage} / 5 页`;
// Fake loading effect
const list = document.querySelector('.instance-list');
list.style.opacity = '0.5';
setTimeout(() => {
list.style.opacity = '1';
// Scroll to top
list.scrollIntoView({behavior: "smooth"});
}, 300);
}
function changePageSize(select) {
showToast(`分页设置已更新: ${select.value}`);
}
// 6. Billing & Ads
function openRecharge() {
if(confirm("将跳转至支付网关 (Alipay/WeChat)...")) {
showToast("正在跳转支付页面...");
}
}
function openProductIntro(product) {
showToast(`正在打开产品文档: ${product}...`);
}
// Override generic confirmDelete
window.confirmDelete = function(instanceId, isHard) {
if(confirm(`警告: 确定要${isHard ? '彻底销毁' : '强制停止'}实例 [${instanceId}] 吗?\n此操作不可逆!`)) {
showToast('操作已提交');
}
};
</script>
</body>