LLM-test/test/code/4/mimo-v2-flash.html

2587 lines
98 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NEON-OS | 赛博朋克未来操作系统</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Roboto+Mono:wght@300;400;500&display=swap" rel="stylesheet">
<style>
:root {
--neon-pink: #ff2a6d;
--neon-blue: #05d9e8;
--neon-purple: #d100d1;
--neon-cyan: #00ff9f;
--dark-bg: #0d0d16;
--glass-bg: rgba(13, 13, 22, 0.7);
--glass-border: rgba(5, 217, 232, 0.3);
--scan-line: rgba(0, 255, 159, 0.05);
--grid-color: rgba(255, 42, 109, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
font-family: 'Roboto Mono', monospace;
background-color: var(--dark-bg);
color: var(--neon-blue);
overflow: hidden;
height: 100vh;
width: 100vw;
position: relative;
}
/* 桌面背景 */
.desktop-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
linear-gradient(rgba(13, 13, 22, 0.9), rgba(13, 13, 22, 0.7)),
repeating-linear-gradient(0deg, transparent, transparent 2px, var(--grid-color) 2px, var(--grid-color) 3px),
repeating-linear-gradient(90deg, transparent, transparent 2px, var(--grid-color) 2px, var(--grid-color) 3px);
z-index: -2;
}
.scan-lines {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, transparent 50%, var(--scan-line) 51%);
background-size: 100% 4px;
z-index: -1;
animation: scanline 8s linear infinite;
pointer-events: none;
}
@keyframes scanline {
0% { background-position: 0 0; }
100% { background-position: 0 100%; }
}
/* 开机动画 */
#boot-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--dark-bg);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10000;
transition: opacity 0.5s ease;
}
.boot-logo {
font-family: 'Orbitron', sans-serif;
font-size: 3rem;
font-weight: 900;
color: var(--neon-pink);
text-shadow: 0 0 10px var(--neon-pink), 0 0 20px var(--neon-pink), 0 0 40px var(--neon-pink);
margin-bottom: 20px;
animation: flicker 2s infinite;
}
.boot-text {
color: var(--neon-cyan);
font-size: 0.9rem;
letter-spacing: 2px;
margin-top: 10px;
}
.boot-progress {
width: 300px;
height: 4px;
background: rgba(255, 255, 255, 0.1);
margin-top: 30px;
position: relative;
overflow: hidden;
}
.boot-progress-bar {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0%;
background: var(--neon-blue);
box-shadow: 0 0 10px var(--neon-blue);
animation: bootProgress 3s ease forwards;
}
@keyframes bootProgress {
to { width: 100%; }
}
@keyframes flicker {
0%, 19%, 21%, 23%, 25%, 54%, 56%, 100% { opacity: 1; }
20%, 24%, 55% { opacity: 0.4; }
}
/* 锁屏界面 */
#lock-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(13, 13, 22, 0.95);
backdrop-filter: blur(10px);
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9000;
}
.lock-Time {
font-family: 'Orbitron', sans-serif;
font-size: 5rem;
color: var(--neon-pink);
text-shadow: 0 0 20px var(--neon-pink);
margin-bottom: 20px;
}
.lock-Date {
font-size: 1.5rem;
color: var(--neon-cyan);
margin-bottom: 30px;
}
.lock-input {
background: rgba(5, 217, 232, 0.1);
border: 1px solid var(--neon-blue);
color: var(--neon-blue);
padding: 12px 20px;
font-family: 'Roboto Mono', monospace;
font-size: 1rem;
width: 300px;
text-align: center;
outline: none;
transition: all 0.3s;
border-radius: 4px;
}
.lock-input:focus {
box-shadow: 0 0 15px var(--neon-blue);
background: rgba(5, 217, 232, 0.2);
}
.lock-buttons {
margin-top: 20px;
display: flex;
gap: 15px;
}
.lock-btn {
padding: 10px 20px;
background: rgba(5, 217, 232, 0.1);
border: 1px solid var(--neon-blue);
color: var(--neon-blue);
cursor: pointer;
border-radius: 4px;
transition: all 0.2s;
font-family: 'Roboto Mono', monospace;
}
.lock-btn:hover {
background: var(--neon-blue);
color: var(--dark-bg);
box-shadow: 0 0 15px var(--neon-blue);
}
.lock-hint {
margin-top: 15px;
color: var(--neon-purple);
font-size: 0.8rem;
cursor: pointer;
}
/* 桌面 - 修复显示问题 */
#desktop {
display: none; /* 默认隐藏通过JS控制显示 */
width: 100%;
height: 100%;
position: relative;
background: var(--dark-bg);
}
/* 当桌面显示时,覆盖所有内容 */
#desktop.active {
display: block !important;
}
/* 桌面小部件 */
.desktop-widgets {
position: absolute;
top: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 100;
}
.widget {
background: var(--glass-bg);
border: 1px solid var(--glass-border);
backdrop-filter: blur(10px);
padding: 15px;
border-radius: 8px;
min-width: 200px;
box-shadow: 0 0 20px rgba(5, 217, 232, 0.2);
}
.widget-title {
font-family: 'Orbitron', sans-serif;
font-size: 0.8rem;
color: var(--neon-cyan);
margin-bottom: 10px;
text-transform: uppercase;
}
.widget-content {
font-size: 0.9rem;
color: var(--neon-blue);
}
.system-monitor-bars {
display: flex;
flex-direction: column;
gap: 5px;
margin-top: 10px;
}
.monitor-bar {
height: 6px;
background: rgba(255, 255, 255, 0.1);
border-radius: 3px;
overflow: hidden;
position: relative;
}
.monitor-bar-fill {
height: 100%;
background: var(--neon-pink);
box-shadow: 0 0 5px var(--neon-pink);
transition: width 0.5s ease;
}
/* 桌面图标 */
.desktop-icons {
position: absolute;
top: 20px;
left: 20px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
z-index: 50;
}
.desktop-icon {
width: 80px;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
transition: all 0.2s;
padding: 10px;
border-radius: 8px;
}
.desktop-icon:hover {
background: rgba(255, 42, 109, 0.2);
box-shadow: 0 0 15px var(--neon-pink);
transform: scale(1.05);
}
.desktop-icon i {
font-size: 2rem;
margin-bottom: 5px;
color: var(--neon-blue);
text-shadow: 0 0 10px var(--neon-blue);
}
.desktop-icon span {
font-size: 0.7rem;
color: var(--neon-cyan);
text-align: center;
}
/* 任务栏 */
#taskbar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
background: var(--glass-bg);
backdrop-filter: blur(10px);
border-top: 1px solid var(--glass-border);
display: flex;
align-items: center;
padding: 0 20px;
z-index: 8000;
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.5);
}
.taskbar-start {
font-family: 'Orbitron', sans-serif;
font-weight: 700;
color: var(--neon-pink);
cursor: pointer;
padding: 8px 15px;
border: 1px solid var(--neon-pink);
border-radius: 4px;
transition: all 0.2s;
margin-right: 20px;
}
.taskbar-start:hover {
background: var(--neon-pink);
color: var(--dark-bg);
box-shadow: 0 0 15px var(--neon-pink);
}
.taskbar-apps {
display: flex;
gap: 10px;
flex-grow: 1;
}
.taskbar-app {
padding: 8px 15px;
background: rgba(5, 217, 232, 0.1);
border: 1px solid rgba(5, 217, 232, 0.3);
color: var(--neon-blue);
cursor: pointer;
border-radius: 4px;
transition: all 0.2s;
font-size: 0.8rem;
}
.taskbar-app:hover {
background: rgba(5, 217, 232, 0.2);
box-shadow: 0 0 10px rgba(5, 217, 232, 0.3);
}
.taskbar-app.active {
background: var(--neon-blue);
color: var(--dark-bg);
box-shadow: 0 0 15px var(--neon-blue);
}
.taskbar-system {
display: flex;
gap: 15px;
align-items: center;
}
.taskbar-icon {
color: var(--neon-cyan);
cursor: pointer;
transition: all 0.2s;
}
.taskbar-icon:hover {
color: var(--neon-pink);
text-shadow: 0 0 10px var(--neon-pink);
}
.taskbar-clock {
font-family: 'Orbitron', sans-serif;
color: var(--neon-purple);
font-size: 0.9rem;
min-width: 80px;
text-align: right;
}
/* 开始菜单 */
#start-menu {
position: absolute;
bottom: 50px;
left: 20px;
width: 300px;
background: var(--glass-bg);
backdrop-filter: blur(15px);
border: 1px solid var(--glass-border);
border-radius: 8px;
padding: 20px;
display: none;
z-index: 8500;
box-shadow: 0 0 30px rgba(5, 217, 232, 0.3);
}
.start-menu-title {
font-family: 'Orbitron', sans-serif;
color: var(--neon-pink);
font-size: 1.2rem;
margin-bottom: 20px;
text-align: center;
}
.start-menu-apps {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 20px;
}
.start-menu-app {
padding: 10px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 10px;
}
.start-menu-app:hover {
background: rgba(5, 217, 232, 0.2);
border-color: var(--neon-blue);
box-shadow: 0 0 10px rgba(5, 217, 232, 0.3);
}
.start-menu-app i {
width: 20px;
text-align: center;
color: var(--neon-cyan);
}
.start-menu-options {
border-top: 1px solid rgba(255, 255, 255, 0.1);
padding-top: 15px;
display: flex;
flex-direction: column;
gap: 8px;
}
.start-menu-option {
padding: 8px;
cursor: pointer;
border-radius: 4px;
transition: all 0.2s;
color: var(--neon-purple);
text-align: center;
}
.start-menu-option:hover {
background: rgba(255, 42, 109, 0.2);
box-shadow: 0 0 10px rgba(255, 42, 109, 0.3);
color: var(--neon-pink);
}
/* 窗口系统 */
.window {
position: absolute;
background: var(--glass-bg);
backdrop-filter: blur(15px);
border: 1px solid var(--glass-border);
border-radius: 8px 8px 0 0;
display: flex;
flex-direction: column;
min-width: 300px;
min-height: 200px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
transition: transform 0.2s, box-shadow 0.2s;
overflow: hidden;
}
.window.active {
border-color: var(--neon-blue);
box-shadow: 0 10px 30px rgba(5, 217, 232, 0.3);
}
.window-header {
background: rgba(5, 217, 232, 0.1);
padding: 8px 12px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: move;
border-bottom: 1px solid rgba(5, 217, 232, 0.2);
}
.window-title {
font-family: 'Orbitron', sans-serif;
font-size: 0.9rem;
color: var(--neon-blue);
display: flex;
align-items: center;
gap: 8px;
}
.window-controls {
display: flex;
gap: 8px;
}
.window-control {
width: 12px;
height: 12px;
border-radius: 50%;
cursor: pointer;
transition: all 0.2s;
}
.window-control.close {
background: var(--neon-pink);
box-shadow: 0 0 5px var(--neon-pink);
}
.window-control.minimize {
background: var(--neon-cyan);
box-shadow: 0 0 5px var(--neon-cyan);
}
.window-control.maximize {
background: var(--neon-purple);
box-shadow: 0 0 5px var(--neon-purple);
}
.window-control:hover {
transform: scale(1.2);
}
.window-body {
flex: 1;
padding: 15px;
overflow: auto;
color: var(--neon-blue);
}
.window-resize {
position: absolute;
right: 0;
bottom: 0;
width: 20px;
height: 20px;
cursor: nwse-resize;
background: linear-gradient(135deg, transparent 50%, var(--neon-blue) 50%);
opacity: 0.5;
}
/* 终端 */
.terminal {
font-family: 'Roboto Mono', monospace;
background: rgba(0, 0, 0, 0.7);
height: 100%;
display: flex;
flex-direction: column;
}
.terminal-output {
flex: 1;
padding: 10px;
overflow-y: auto;
white-space: pre-wrap;
font-size: 0.9rem;
line-height: 1.4;
}
.terminal-input-line {
display: flex;
padding: 10px;
background: rgba(5, 217, 232, 0.1);
}
.terminal-prompt {
color: var(--neon-green);
margin-right: 8px;
}
.terminal-input {
background: transparent;
border: none;
outline: none;
color: var(--neon-blue);
flex: 1;
font-family: 'Roboto Mono', monospace;
font-size: 0.9rem;
}
.terminal .green { color: var(--neon-cyan); }
.terminal .pink { color: var(--neon-pink); }
.terminal .purple { color: var(--neon-purple); }
.terminal .error { color: #ff5555; }
/* 通知系统 */
#notification-area {
position: absolute;
top: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 10px;
width: 300px;
z-index: 9500;
}
.notification {
background: var(--glass-bg);
backdrop-filter: blur(15px);
border: 1px solid var(--glass-border);
border-radius: 8px;
padding: 15px;
animation: slideIn 0.3s ease;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);
position: relative;
overflow: hidden;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.notification-header {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
align-items: center;
}
.notification-title {
font-family: 'Orbitron', sans-serif;
font-size: 0.9rem;
color: var(--neon-pink);
}
.notification-close {
cursor: pointer;
color: var(--neon-cyan);
opacity: 0.7;
}
.notification-close:hover {
opacity: 1;
color: var(--neon-pink);
}
.notification-body {
font-size: 0.8rem;
color: var(--neon-blue);
line-height: 1.4;
}
.notification.success { border-left: 3px solid var(--neon-cyan); }
.notification.error { border-left: 3px solid #ff5555; }
.notification.warning { border-left: 3px solid #ffaa00; }
.notification.info { border-left: 3px solid var(--neon-blue); }
/* 右键菜单 */
#context-menu {
position: absolute;
background: var(--glass-bg);
backdrop-filter: blur(15px);
border: 1px solid var(--glass-border);
border-radius: 8px;
padding: 8px 0;
display: none;
z-index: 10000;
min-width: 180px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
.context-menu-item {
padding: 10px 15px;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
gap: 10px;
color: var(--neon-blue);
font-size: 0.9rem;
}
.context-menu-item:hover {
background: rgba(5, 217, 232, 0.2);
color: var(--neon-cyan);
}
.context-menu-item i {
width: 20px;
text-align: center;
}
.context-menu-divider {
height: 1px;
background: rgba(255, 255, 255, 0.1);
margin: 5px 0;
}
/* 矩阵雨画布 */
#matrix-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
display: none;
background: black;
}
/* 隐藏类 - 用于灵活控制 */
.hidden {
display: none !important;
}
</style>
</head>
<body>
<!-- 开机动画 -->
<div id="boot-screen">
<div class="boot-logo">NEON-OS</div>
<div class="boot-text">初始化系统核心模块...</div>
<div class="boot-progress">
<div class="boot-progress-bar"></div>
</div>
</div>
<!-- 锁屏界面 -->
<div id="lock-screen">
<div class="lock-Time" id="lock-time">00:00</div>
<div class="lock-Date" id="lock-date">加载中...</div>
<input type="password" class="lock-input" placeholder="输入密码或点击跳过" id="lock-password">
<div class="lock-buttons">
<button class="lock-btn" onclick="unlockSystem()">进入系统</button>
<button class="lock-btn" onclick="skipLockScreen()">跳过</button>
</div>
<div class="lock-hint">提示:直接点击"跳过"即可进入</div>
</div>
<!-- 桌面 -->
<div id="desktop" style="display:none;">
<div class="desktop-bg"></div>
<div class="scan-lines"></div>
<!-- 桌面小部件 -->
<div class="desktop-widgets">
<div class="widget">
<div class="widget-title">系统时钟</div>
<div class="widget-content" id="widget-clock">00:00:00</div>
</div>
<div class="widget">
<div class="widget-title">系统状态</div>
<div class="widget-content" id="widget-status">运行中</div>
<div class="system-monitor-bars">
<div class="monitor-bar">
<div class="monitor-bar-fill" id="cpu-bar" style="width: 45%"></div>
</div>
<div class="monitor-bar">
<div class="monitor-bar-fill" id="mem-bar" style="width: 62%"></div>
</div>
</div>
</div>
<div class="widget">
<div class="widget-title">快速命令</div>
<div class="widget-content" style="cursor: pointer; padding: 5px;">
<div style="margin: 5px 0;" onclick="openTerminal()">打开终端</div>
<div style="margin: 5px 0;" onclick="showNotification('info', '系统信息', 'NEON-OS 版本 1.0.0')">系统信息</div>
</div>
</div>
</div>
<!-- 桌面图标 -->
<div class="desktop-icons">
<div class="desktop-icon" onclick="openApp('file-manager')">
<i class="fas fa-folder"></i>
<span>文件管理器</span>
</div>
<div class="desktop-icon" onclick="openTerminal()">
<i class="fas fa-terminal"></i>
<span>终端</span>
</div>
<div class="desktop-icon" onclick="openApp('browser')">
<i class="fas fa-globe"></i>
<span>浏览器</span>
</div>
<div class="desktop-icon" onclick="openApp('settings')">
<i class="fas fa-cog"></i>
<span>设置中心</span>
</div>
<div class="desktop-icon" onclick="openApp('music-player')">
<i class="fas fa-music"></i>
<span>音乐播放器</span>
</div>
<div class="desktop-icon" onclick="openApp('notepad')">
<i class="fas fa-sticky-note"></i>
<span>便签</span>
</div>
<div class="desktop-icon" onclick="openApp('monitor')">
<i class="fas fa-chart-line"></i>
<span>系统监控</span>
</div>
<div class="desktop-icon" onclick="openApp('about')">
<i class="fas fa-info-circle"></i>
<span>关于系统</span>
</div>
</div>
<!-- 任务栏 -->
<div id="taskbar">
<div class="taskbar-start" onclick="toggleStartMenu()">
<i class="fas fa-power-off"></i> 开始
</div>
<div class="taskbar-apps" id="taskbar-apps"></div>
<div class="taskbar-system">
<i class="fas fa-bell taskbar-icon" onclick="showNotification('info', '通知中心', '暂无新通知')"></i>
<i class="fas fa-volume-up taskbar-icon" onclick="toggleVolume()"></i>
<div class="taskbar-clock" id="taskbar-clock">00:00</div>
</div>
</div>
<!-- 开始菜单 -->
<div id="start-menu">
<div class="user-avatar">NE</div>
<div class="start-menu-title">NEON-OS</div>
<div class="start-menu-apps">
<div class="start-menu-app" onclick="openApp('file-manager')">
<i class="fas fa-folder"></i> 文件管理器
</div>
<div class="start-menu-app" onclick="openTerminal()">
<i class="fas fa-terminal"></i> 终端
</div>
<div class="start-menu-app" onclick="openApp('browser')">
<i class="fas fa-globe"></i> 浏览器
</div>
<div class="start-menu-app" onclick="openApp('settings')">
<i class="fas fa-cog"></i> 设置中心
</div>
</div>
<div class="start-menu-options">
<div class="start-menu-option" onclick="rebootSystem()">重启系统</div>
<div class="start-menu-option" onclick="logout()">切换用户</div>
<div class="start-menu-option" onclick="shutdown()">关机</div>
</div>
</div>
<!-- 通知区域 -->
<div id="notification-area"></div>
<!-- 右键菜单 -->
<div id="context-menu">
<div class="context-menu-item" onclick="refreshDesktop()">
<i class="fas fa-sync-alt"></i> 刷新
</div>
<div class="context-menu-item" onclick="openApp('settings')">
<i class="fas fa-cog"></i> 个性化设置
</div>
<div class="context-menu-divider"></div>
<div class="context-menu-item" onclick="openApp('about')">
<i class="fas fa-info-circle"></i> 关于 NEON-OS
</div>
</div>
<!-- 矩阵雨画布 -->
<canvas id="matrix-canvas"></canvas>
</div>
<script>
// 全局状态管理
const state = {
apps: {},
nextZIndex: 100,
settings: {
theme: 'cyberpunk',
volume: 0.7,
wallpaper: 'default',
notifications: true
},
fileSystem: {
root: {
type: 'folder',
children: {
'Documents': {
type: 'folder',
children: {
'readme.txt': { type: 'file', content: '欢迎使用 NEON-OS!\n这是一个赛博朋克风格的操作系统。\n尝试在终端输入 help 查看可用命令。' },
'notes.txt': { type: 'file', content: '我的笔记:\n- 优化render循环\n- 修复拖拽bug\n- 添加更多命令' }
}
},
'Projects': {
type: 'folder',
children: {
'neon-os.html': { type: 'file', content: '<!DOCTYPE html>\n<!-- 这是我们之前的工作 -->' },
'design.fig': { type: 'file', content: '二进制文件预览:\n[FIGMA设计原型数据]' }
}
},
'Music': {
type: 'folder',
children: {
'synthwave.mp3': { type: 'file', content: '音频文件' },
'cyberpunk.flac': { type: 'file', content: '无损音频' }
}
},
'config.json': { type: 'file', content: '{\n "theme": "cyberpunk",\n "notifications": true\n}' }
}
}
},
currentDirectory: [],
musicPlayer: {
playing: false,
currentTrack: 0,
tracks: [
{ title: '霓虹之夜', artist: 'SynthWave', duration: 180 },
{ title: '数字梦境', artist: 'CyberPunk', duration: 220 },
{ title: '未来都市', artist: 'NeoTokyo', duration: 200 }
]
},
terminalHistory: [],
matrixRunning: false
};
// 初始化系统
function initSystem() {
console.log('[SYSTEM] 正在初始化...');
const savedSettings = localStorage.getItem('neon-os-settings');
if (savedSettings) {
try {
const parsed = JSON.parse(savedSettings);
state.settings = { ...state.settings, ...parsed };
console.log('[SYSTEM] 设置已加载');
} catch (e) {
console.log('[SYSTEM] 设置加载失败,使用默认值');
}
}
setTimeout(() => {
const bootScreen = document.getElementById('boot-screen');
if (bootScreen) {
bootScreen.style.opacity = '0';
setTimeout(() => {
bootScreen.style.display = 'none';
showLockScreen();
}, 500);
}
}, 2000); // 缩短开机动画时间,加快测试
}
// 显示锁屏
function showLockScreen() {
console.log('[LOCK] 显示锁屏界面');
const lockScreen = document.getElementById('lock-screen');
if (lockScreen) {
lockScreen.style.display = 'flex';
}
updateLockTime();
setInterval(updateLockTime, 1000);
const passwordInput = document.getElementById('lock-password');
const hint = document.querySelector('.lock-hint');
if (passwordInput) {
passwordInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
unlockSystem();
}
});
}
if (hint) {
hint.addEventListener('click', skipLockScreen);
}
}
function updateLockTime() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const timeStr = `${hours}:${minutes}:${seconds}`;
const dateStr = now.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
});
const lockTime = document.getElementById('lock-time');
const lockDate = document.getElementById('lock-date');
if (lockTime) lockTime.textContent = timeStr;
if (lockDate) lockDate.textContent = dateStr;
const taskbarClock = document.getElementById('taskbar-clock');
if (taskbarClock) {
taskbarClock.textContent = `${hours}:${minutes}`;
}
const widgetClock = document.getElementById('widget-clock');
if (widgetClock) {
widgetClock.textContent = timeStr;
}
}
// 跳过锁屏(直接进入)
function skipLockScreen() {
console.log('[LOCK] 跳过锁屏,直接进入系统');
unlockSystem();
}
// 解锁系统 - 修复显示问题
function unlockSystem() {
console.log('[UNLOCK] 开始解锁流程');
const lockScreen = document.getElementById('lock-screen');
const desktop = document.getElementById('desktop');
if (!lockScreen || !desktop) {
console.error('[UNLOCK] 必要元素未找到');
return;
}
// 简化解锁流程
lockScreen.style.opacity = '0';
console.log('[UNLOCK] 锁屏透明度设置为0');
setTimeout(() => {
console.log('[UNLOCK] 隐藏锁屏,显示桌面');
lockScreen.style.display = 'none';
// 显示桌面 - 使用多种方式确保显示
desktop.style.display = 'block';
desktop.classList.remove('hidden');
desktop.classList.add('active');
console.log('[UNLOCK] 桌面display样式:', desktop.style.display);
console.log('[UNLOCK] 桌面classList:', desktop.className);
// 启动桌面动画
try {
startDesktopAnimation();
console.log('[UNLOCK] 桌面动画已启动');
} catch (e) {
console.error('[UNLOCK] 桌面动画启动失败:', e);
}
// 显示欢迎通知
setTimeout(() => {
showNotification('success', '系统启动', '欢迎回来,用户');
console.log('[UNLOCK] 已显示欢迎通知');
}, 500);
setTimeout(() => {
showNotification('info', '提示', '右键点击桌面访问菜单,或使用开始菜单打开应用');
}, 3000);
}, 500);
}
// 桌面动画
function startDesktopAnimation() {
console.log('[ANIM] 开始桌面监控动画');
// CPU/内存监控
setInterval(() => {
if (!document.getElementById('desktop') || document.getElementById('desktop').style.display === 'none') return;
const cpu = Math.floor(Math.random() * 30) + 20;
const mem = Math.floor(Math.random() * 30) + 40;
const cpuBar = document.getElementById('cpu-bar');
const memBar = document.getElementById('mem-bar');
if (cpuBar) cpuBar.style.width = cpu + '%';
if (memBar) memBar.style.width = mem + '%';
}, 2000);
// 随机通知
setInterval(() => {
if (!document.getElementById('desktop') || document.getElementById('desktop').style.display === 'none') return;
if (Math.random() > 0.9 && state.settings.notifications) {
const messages = [
{ type: 'info', title: '系统更新', msg: '检查到可用的系统更新' },
{ type: 'success', title: '备份完成', msg: '所有文件已自动备份' },
{ type: 'warning', title: '磁盘空间', msg: 'C盘剩余空间不足20%' }
];
const msg = messages[Math.floor(Math.random() * messages.length)];
showNotification(msg.type, msg.title, msg.msg);
}
}, 15000);
}
// 窗口管理系统(保持原有逻辑,略作简化)
function createWindow(appId, title, icon, initialContent = '') {
if (state.apps[appId]) {
activateWindow(appId);
return;
}
const window = document.createElement('div');
window.className = 'window';
window.id = `window-${appId}`;
window.style.left = '100px';
window.style.top = '100px';
window.style.width = '600px';
window.style.height = '400px';
window.style.zIndex = state.nextZIndex++;
window.innerHTML = `
<div class="window-header" data-app="${appId}">
<div class="window-title">
<i class="${icon}"></i>
<span>${title}</span>
</div>
<div class="window-controls">
<div class="window-control minimize" onclick="minimizeWindow('${appId}')"></div>
<div class="window-control maximize" onclick="maximizeWindow('${appId}')"></div>
<div class="window-control close" onclick="closeWindow('${appId}')"></div>
</div>
</div>
<div class="window-body" id="body-${appId}">
${initialContent}
</div>
<div class="window-resize" data-app="${appId}"></div>
`;
document.getElementById('desktop').appendChild(window);
state.apps[appId] = {
element: window,
minimized: false,
maximized: false,
originalSize: { width: '600px', height: '400px', left: '100px', top: '100px' }
};
makeDraggable(window);
makeResizable(window);
activateWindow(appId);
addToTaskbar(appId, title, icon);
}
function makeDraggable(element) {
const header = element.querySelector('.window-header');
let isDragging = false;
let currentX, currentY, initialX, initialY;
header.addEventListener('mousedown', (e) => {
if (e.target.classList.contains('window-control')) return;
isDragging = true;
initialX = e.clientX - element.offsetLeft;
initialY = e.clientY - element.offsetTop;
activateWindow(element.id.replace('window-', ''));
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
currentX = Math.max(0, Math.min(currentX, window.innerWidth - element.offsetWidth));
currentY = Math.max(0, Math.min(currentY, window.innerHeight - 50));
element.style.left = currentX + 'px';
element.style.top = currentY + 'px';
});
document.addEventListener('mouseup', () => { isDragging = false; });
}
function makeResizable(element) {
const resizeHandle = element.querySelector('.window-resize');
let isResizing = false;
let startX, startY, startWidth, startHeight;
resizeHandle.addEventListener('mousedown', (e) => {
isResizing = true;
startX = e.clientX;
startY = e.clientY;
startWidth = element.offsetWidth;
startHeight = element.offsetHeight;
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!isResizing) return;
const newWidth = startWidth + (e.clientX - startX);
const newHeight = startHeight + (e.clientY - startY);
if (newWidth > 300) element.style.width = newWidth + 'px';
if (newHeight > 200) element.style.height = newHeight + 'px';
});
document.addEventListener('mouseup', () => { isResizing = false; });
}
function activateWindow(appId) {
const app = state.apps[appId];
if (!app) return;
app.element.style.zIndex = state.nextZIndex++;
Object.values(state.apps).forEach(appItem => appItem.element.classList.remove('active'));
app.element.classList.add('active');
if (app.minimized) {
app.element.style.display = 'flex';
app.minimized = false;
updateTaskbarActive(appId);
}
}
function minimizeWindow(appId) {
const app = state.apps[appId];
if (!app) return;
app.element.style.display = 'none';
app.minimized = true;
updateTaskbarActive(appId);
}
function maximizeWindow(appId) {
const app = state.apps[appId];
if (!app) return;
if (app.maximized) {
app.element.style.width = app.originalSize.width;
app.element.style.height = app.originalSize.height;
app.element.style.left = app.originalSize.left;
app.element.style.top = app.originalSize.top;
app.maximized = false;
} else {
app.originalSize = {
width: app.element.style.width,
height: app.element.style.height,
left: app.element.style.left,
top: app.element.style.top
};
app.element.style.width = '100%';
app.element.style.height = 'calc(100% - 50px)';
app.element.style.left = '0';
app.element.style.top = '0';
app.maximized = true;
const body = document.getElementById(`body-${appId}`);
if (body) body.style.height = 'calc(100% - 41px)';
}
activateWindow(appId);
}
function closeWindow(appId) {
const app = state.apps[appId];
if (!app) return;
if (appId === 'music-player' && state.musicPlayer.playing) {
state.musicPlayer.playing = false;
stopMusicProgress();
}
if (appId === 'monitor') {
stopMonitorCharts();
}
app.element.remove();
delete state.apps[appId];
removeFromTaskbar(appId);
}
// 任务栏管理
function addToTaskbar(appId, title, icon) {
const taskbarApps = document.getElementById('taskbar-apps');
const appButton = document.createElement('div');
appButton.className = 'taskbar-app';
appButton.id = `taskbar-${appId}`;
appButton.innerHTML = `<i class="${icon}"></i> ${title}`;
appButton.onclick = () => {
if (state.apps[appId].minimized) {
activateWindow(appId);
} else {
minimizeWindow(appId);
}
};
taskbarApps.appendChild(appButton);
updateTaskbarActive(appId);
}
function removeFromTaskbar(appId) {
const button = document.getElementById(`taskbar-${appId}`);
if (button) button.remove();
}
function updateTaskbarActive(appId) {
const buttons = document.querySelectorAll('.taskbar-app');
buttons.forEach(btn => btn.classList.remove('active'));
if (state.apps[appId] && !state.apps[appId].minimized) {
const activeButton = document.getElementById(`taskbar-${appId}`);
if (activeButton) activeButton.classList.add('active');
}
}
// 应用程序逻辑
function openApp(appId) {
switch(appId) {
case 'file-manager': openFileManager(); break;
case 'browser': openBrowser(); break;
case 'settings': openSettings(); break;
case 'music-player': openMusicPlayer(); break;
case 'notepad': openNotepad(); break;
case 'monitor': openMonitor(); break;
case 'about': openAbout(); break;
}
}
function openTerminal() {
if (state.apps['terminal']) {
activateWindow('terminal');
return;
}
const initialContent = `
<div class="terminal">
<div class="terminal-output" id="terminal-output"></div>
<div class="terminal-input-line">
<span class="terminal-prompt">user@neon-os:~$</span>
<input type="text" class="terminal-input" id="terminal-input" placeholder="输入 help 查看可用命令">
</div>
</div>
`;
createWindow('terminal', '终端模拟器', 'fas fa-terminal', initialContent);
setTimeout(() => {
const input = document.getElementById('terminal-input');
const output = document.getElementById('terminal-output');
if (output) {
output.innerHTML = `
<span class="green">NEON-OS 终端模拟器 v1.0</span>
<br><span class="purple">输入 'help' 查看可用命令</span>
<br>
`;
}
if (input) {
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter') {
const command = input.value.trim();
if (command) {
state.terminalHistory.push(command);
executeCommand(command, output);
input.value = '';
output.scrollTop = output.scrollHeight;
}
} else if (e.key === 'ArrowUp') {
if (state.terminalHistory.length > 0) {
input.value = state.terminalHistory[state.terminalHistory.length - 1];
}
}
});
input.focus();
}
}, 100);
}
function executeCommand(command, output) {
const parts = command.split(' ');
const cmd = parts[0].toLowerCase();
const args = parts.slice(1);
const prompt = document.createElement('div');
prompt.innerHTML = `<span class="terminal-prompt">user@neon-os:~$</span> ${command}`;
output.appendChild(prompt);
let response = '';
switch(cmd) {
case 'help':
response = '可用命令:\nhelp - 显示此帮助信息\nclear - 清屏\ndate - 显示当前日期时间\nwhoami - 显示当前用户\nls - 列出文件\ncd - 切换目录\ncat - 查看文件内容\necho - 输出文本\nneofetch - 显示系统信息\nmatrix - 启动矩阵雨特效\ntheme - 切换主题\nreboot - 重启系统\nexit - 关闭终端';
break;
case 'clear':
output.innerHTML = '';
return;
case 'date':
response = new Date().toString();
break;
case 'whoami':
response = 'user@neon-os';
break;
case 'ls':
const currentDir = getCurrentDirectory();
if (typeof currentDir === 'object') {
response = Object.keys(currentDir.children).map(name => {
const item = currentDir.children[name];
return item.type === 'folder' ? `<span class="green">${name}/</span>` : name;
}).join(' ');
} else {
response = '<span class="error">错误:无法读取目录</span>';
}
break;
case 'cd':
if (args.length === 0) {
state.currentDirectory = [];
response = '已返回根目录';
} else if (args[0] === '..') {
if (state.currentDirectory.length > 0) {
state.currentDirectory.pop();
response = '已返回上级目录';
} else {
response = '已在根目录';
}
} else {
const currentDir = getCurrentDirectory();
if (currentDir.children && currentDir.children[args[0]] && currentDir.children[args[0]].type === 'folder') {
state.currentDirectory.push(args[0]);
response = `已切换到 /${state.currentDirectory.join('/')}`;
} else {
response = `<span class="error">目录不存在: ${args[0]}</span>`;
}
}
break;
case 'cat':
if (args.length === 0) {
response = '<span class="error">用法: cat &lt;文件名&gt;</span>';
} else {
const currentDir = getCurrentDirectory();
if (currentDir.children && currentDir.children[args[0]] && currentDir.children[args[0]].type === 'file') {
const content = currentDir.children[args[0]].content;
response = `<pre>${content}</pre>`;
} else {
response = `<span class="error">文件不存在: ${args[0]}</span>`;
}
}
break;
case 'echo':
response = args.join(' ');
break;
case 'neofetch':
response = '<span style="color: #ff2a6d; font-weight: bold;">NEON-OS</span> 版本 1.0.0\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n<span style="color: #05d9e8;">内核</span>: CyberKernel 2.6.18\n<span style="color: #d100d1;">架构</span>: WebAssembly x86_64\n<span style="color: #00ff9f;">Shell</span>: NeonTerminal v1.0\n<span style="color: #ff2a6d;">主题</span>: ' + state.settings.theme + '\n<span style="color: #05d9e8;">内存占用</span>: ' + (Math.floor(Math.random() * 30 + 20)) + '% / 16GB\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━';
break;
case 'matrix':
if (!state.matrixRunning) {
startMatrixRain();
response = '<span class="green">矩阵雨已启动... 输入任意命令或刷新页面退出</span>';
} else {
response = '<span class="error">矩阵雨已在运行</span>';
}
break;
case 'theme':
const themes = ['cyberpunk', 'retro', 'minimal', 'dark', 'light'];
const nextTheme = themes[(themes.indexOf(state.settings.theme) + 1) % themes.length];
state.settings.theme = nextTheme;
saveSettings();
applyTheme();
response = '<span class="green">主题已切换至: ' + nextTheme + '</span>';
break;
case 'reboot':
response = '<span class="purple">系统将在3秒后重启...</span>';
setTimeout(rebootSystem, 3000);
break;
case 'exit':
closeWindow('terminal');
return;
case 'mkdir':
case 'touch':
case 'rm':
response = '<span class="error">只读文件系统: ' + cmd + ' 命令已被禁用</span>';
break;
default:
if (command.trim() !== '') {
response = '<span class="error">命令未找到: ' + cmd + '</span>';
} else {
return;
}
}
if (response) {
const responseDiv = document.createElement('div');
responseDiv.style.marginTop = '5px';
responseDiv.innerHTML = response;
output.appendChild(responseDiv);
}
if (response.length > 50) {
const lastChild = output.lastChild;
if (lastChild) {
lastChild.classList.add('typewriter');
setTimeout(() => lastChild.classList.remove('typewriter'), 2000);
}
}
}
function getCurrentDirectory() {
let current = state.fileSystem.root;
for (let dir of state.currentDirectory) {
if (current.children && current.children[dir]) {
current = current.children[dir];
} else {
return state.fileSystem.root;
}
}
return current;
}
function openFileManager() {
if (state.apps['file-manager']) {
activateWindow('file-manager');
return;
}
const content = `
<div class="file-manager">
<div class="fm-sidebar">
<div style="color: var(--neon-cyan); margin-bottom: 10px; font-family: 'Orbitron', sans-serif;">位置</div>
<div style="cursor: pointer; margin-bottom: 8px;" onclick="resetFMPath()">🏠 根目录</div>
<div style="cursor: pointer; margin-bottom: 8px;" onclick="setFMPath(['Documents'])">📁 Documents</div>
<div style="cursor: pointer; margin-bottom: 8px;" onclick="setFMPath(['Projects'])">📁 Projects</div>
<div style="cursor: pointer; margin-bottom: 8px;" onclick="setFMPath(['Music'])">📁 Music</div>
<div style="margin-top: 20px; padding-top: 10px; border-top: 1px solid rgba(5, 217, 232, 0.2);">
<div style="font-size: 0.7rem; color: var(--neon-purple);">
当前: /${state.currentDirectory.join('/')}
</div>
</div>
</div>
<div class="fm-main" id="fm-main"></div>
</div>
`;
createWindow('file-manager', '文件管理器', 'fas fa-folder', content);
setTimeout(() => renderFileManager(), 100);
}
function renderFileManager() {
const fmMain = document.getElementById('fm-main');
if (!fmMain) return;
const current = getCurrentDirectory();
let html = '';
if (state.currentDirectory.length > 0) {
html += `
<div class="fm-item folder" onclick="goUpDirectory()">
<i class="fas fa-level-up-alt"></i>
<span>上一级</span>
</div>
`;
}
if (current.children) {
Object.entries(current.children).forEach(([name, item]) => {
const iconClass = item.type === 'folder' ? 'fas fa-folder' : 'fas fa-file-alt';
const itemClass = item.type === 'folder' ? 'folder' : 'file';
html += `
<div class="fm-item ${itemClass}" oncontextmenu="showFMContextMenu(event, '${name}', '${item.type}')" onclick="openFMItem('${name}', '${item.type}')">
<i class="${iconClass}"></i>
<span>${name}</span>
</div>
`;
});
}
fmMain.innerHTML = html;
}
function setFMPath(path) {
state.currentDirectory = path;
setTimeout(() => renderFileManager(), 50);
}
function resetFMPath() {
state.currentDirectory = [];
setTimeout(() => renderFileManager(), 50);
}
function goUpDirectory() {
if (state.currentDirectory.length > 0) {
state.currentDirectory.pop();
setTimeout(() => renderFileManager(), 50);
}
}
function openFMItem(name, type) {
if (type === 'folder') {
state.currentDirectory.push(name);
setTimeout(() => renderFileManager(), 50);
} else {
const current = getCurrentDirectory();
if (current.children[name]) {
showNotification('info', '文件预览', '文件: ' + name + ' \\n内容已显示在终端使用 cat 命令)');
}
}
}
function showFMContextMenu(event, name, type) {
event.preventDefault();
event.stopPropagation();
const contextMenu = document.getElementById('context-menu');
contextMenu.innerHTML = `
<div class="context-menu-item" onclick="showNotification('info', '属性', '文件: ${name} \\n类型: ${type} \\n大小: ' + (Math.floor(Math.random() * 1000)) + 'KB')">
<i class="fas fa-info-circle"></i> 属性
</div>
<div class="context-menu-item" onclick="showNotification('warning', '权限', '该操作需要管理员权限')">
<i class="fas fa-lock"></i> 权限管理
</div>
${type === 'file' ? `
<div class="context-menu-item" onclick="showNotification('info', '编辑', '在终端使用 cat 查看内容')">
<i class="fas fa-edit"></i> 编辑
</div>
` : ''}
<div class="context-menu-divider"></div>
<div class="context-menu-item" onclick="showNotification('error', '错误', '只读文件系统:无法删除')">
<i class="fas fa-trash"></i> 删除
</div>
`;
contextMenu.style.display = 'block';
contextMenu.style.left = event.pageX + 'px';
contextMenu.style.top = event.pageY + 'px';
setTimeout(() => {
document.addEventListener('click', closeContextMenuOnce);
}, 100);
}
function openBrowser() {
if (state.apps['browser']) {
activateWindow('browser');
return;
}
const content = `
<div class="browser">
<div class="browser-toolbar">
<input type="text" class="browser-url" id="browser-url" value="https://example.com" placeholder="输入URL...">
<button class="browser-btn" onclick="navigateBrowser()">前往</button>
<button class="browser-btn" onclick="refreshBrowser()">刷新</button>
</div>
<div class="browser-content" id="browser-content">
<iframe src="https://example.com"></iframe>
</div>
</div>
`;
createWindow('browser', 'Web浏览器', 'fas fa-globe', content);
}
function navigateBrowser() {
const urlInput = document.getElementById('browser-url');
const content = document.getElementById('browser-content');
if (urlInput && content) {
let url = urlInput.value;
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'https://' + url;
}
content.innerHTML = '<iframe src="' + url + '"></iframe>';
showNotification('info', '浏览器', '正在访问: ' + url);
}
}
function refreshBrowser() {
const content = document.getElementById('browser-content');
if (content) {
const iframe = content.querySelector('iframe');
if (iframe) {
iframe.src = iframe.src;
showNotification('info', '浏览器', '页面已刷新');
}
}
}
function openSettings() {
if (state.apps['settings']) {
activateWindow('settings');
return;
}
const content = `
<div class="settings">
<div class="setting-group">
<h3>主题设置</h3>
<div class="setting-item">
<span class="setting-label">当前主题: ${state.settings.theme}</span>
<div class="setting-control">
<button onclick="changeTheme()">切换主题</button>
</div>
</div>
<div class="setting-item">
<span class="setting-label">壁纸风格</span>
<div class="setting-control">
<button onclick="changeWallpaper()">更换壁纸</button>
</div>
</div>
</div>
<div class="setting-group">
<h3>系统设置</h3>
<div class="setting-item">
<span class="setting-label">音量: ${Math.round(state.settings.volume * 100)}%</span>
<div class="setting-control">
<input type="range" min="0" max="100" value="${state.settings.volume * 100}"
oninput="setVolume(this.value)">
</div>
</div>
<div class="setting-item">
<span class="setting-label">启用通知</span>
<div class="setting-control">
<button onclick="toggleNotifications()">${state.settings.notifications ? '禁用' : '启用'}</button>
</div>
</div>
</div>
<div class="setting-group">
<h3>隐私与安全</h3>
<div class="setting-item">
<span class="setting-label">清除本地数据</span>
<div class="setting-control">
<button onclick="clearData()">清除</button>
</div>
</div>
<div class="setting-item">
<span class="setting-label">导出配置</span>
<div class="setting-control">
<button onclick="exportConfig()">导出</button>
</div>
</div>
</div>
</div>
`;
createWindow('settings', '设置中心', 'fas fa-cog', content);
}
function changeTheme() {
const themes = ['cyberpunk', 'retro', 'minimal', 'dark', 'light'];
const currentIndex = themes.indexOf(state.settings.theme);
const nextIndex = (currentIndex + 1) % themes.length;
state.settings.theme = themes[nextIndex];
saveSettings();
applyTheme();
showNotification('success', '主题切换', '已切换至: ' + themes[nextIndex]);
setTimeout(() => {
if (state.apps['settings']) {
closeWindow('settings');
openSettings();
}
}, 500);
}
function changeWallpaper() {
const wallpapers = ['default', 'neon', 'grid', 'city', 'matrix'];
const currentWallpaper = state.settings.wallpaper;
const nextIndex = (wallpapers.indexOf(currentWallpaper) + 1) % wallpapers.length;
state.settings.wallpaper = wallpapers[nextIndex];
saveSettings();
applyWallpaper();
showNotification('success', '壁纸更换', '已更换为: ' + wallpapers[nextIndex]);
}
function setVolume(value) {
state.settings.volume = value / 100;
saveSettings();
if (state.apps['settings']) {
const label = document.querySelector('.setting-item span');
if (label) {
label.textContent = '音量: ' + value + '%';
}
}
}
function toggleNotifications() {
state.settings.notifications = !state.settings.notifications;
saveSettings();
showNotification('info', '通知设置', '通知已' + (state.settings.notifications ? '启用' : '禁用'));
setTimeout(() => {
if (state.apps['settings']) {
closeWindow('settings');
openSettings();
}
}, 500);
}
function clearData() {
if (confirm('确定要清除所有本地数据吗?这将重置所有设置。')) {
localStorage.removeItem('neon-os-settings');
showNotification('success', '数据清除', '本地数据已清除');
setTimeout(rebootSystem, 1000);
}
}
function exportConfig() {
const config = JSON.stringify(state.settings, null, 2);
showNotification('info', '导出配置', '配置信息已复制到终端(模拟操作)\\n\\n' + config);
}
function openMusicPlayer() {
if (state.apps['music-player']) {
activateWindow('music-player');
return;
}
const content = `
<div class="music-player">
<div class="album-cover">
<i class="fas fa-music"></i>
</div>
<div class="music-info">
<div class="music-title" id="music-title">${state.musicPlayer.tracks[state.musicPlayer.currentTrack].title}</div>
<div class="music-artist" id="music-artist">${state.musicPlayer.tracks[state.musicPlayer.currentTrack].artist}</div>
<div class="progress-bar" onclick="seekMusic(event)">
<div class="progress-fill" id="music-progress"></div>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 0.7rem; color: var(--neon-purple);">
<span id="current-time">0:00</span>
<span id="total-time">${formatTime(state.musicPlayer.tracks[state.musicPlayer.currentTrack].duration)}</span>
</div>
<div class="audio-visualizer" id="audio-visualizer"></div>
</div>
<div class="music-controls">
<div class="music-control" onclick="prevTrack()"><i class="fas fa-step-backward"></i></div>
<div class="music-control" id="play-pause-btn" onclick="togglePlay()"><i class="fas fa-play"></i></div>
<div class="music-control" onclick="nextTrack()"><i class="fas fa-step-forward"></i></div>
</div>
<div class="volume-control">
<i class="fas fa-volume-up"></i>
<input type="range" min="0" max="100" value="${state.settings.volume * 100}" oninput="setTrackVolume(this.value)">
</div>
</div>
`;
createWindow('music-player', '音乐播放器', 'fas fa-music', content);
setTimeout(() => {
if (!state.musicPlayer.playing) {
createAudioVisualizer();
}
}, 100);
}
function togglePlay() {
state.musicPlayer.playing = !state.musicPlayer.playing;
const btn = document.getElementById('play-pause-btn');
if (btn) {
btn.innerHTML = state.musicPlayer.playing ? '<i class="fas fa-pause"></i>' : '<i class="fas fa-play"></i>';
}
if (state.musicPlayer.playing) {
showNotification('info', '音乐播放器', '正在播放: ' + state.musicPlayer.tracks[state.musicPlayer.currentTrack].title);
startMusicProgress();
} else {
showNotification('info', '音乐播放器', '已暂停');
stopMusicProgress();
}
}
function prevTrack() {
const currentIndex = state.musicPlayer.currentTrack;
state.musicPlayer.currentTrack = currentIndex > 0 ? currentIndex - 1 : state.musicPlayer.tracks.length - 1;
updateTrackInfo();
showNotification('info', '音乐切换', '播放: ' + state.musicPlayer.tracks[state.musicPlayer.currentTrack].title);
}
function nextTrack() {
const currentIndex = state.musicPlayer.currentTrack;
state.musicPlayer.currentTrack = (currentIndex + 1) % state.musicPlayer.tracks.length;
updateTrackInfo();
showNotification('info', '音乐切换', '播放: ' + state.musicPlayer.tracks[state.musicPlayer.currentTrack].title);
}
function updateTrackInfo() {
const track = state.musicPlayer.tracks[state.musicPlayer.currentTrack];
const titleEl = document.getElementById('music-title');
const artistEl = document.getElementById('music-artist');
const totalTimeEl = document.getElementById('total-time');
if (titleEl) titleEl.textContent = track.title;
if (artistEl) artistEl.textContent = track.artist;
if (totalTimeEl) totalTimeEl.textContent = formatTime(track.duration);
const progress = document.getElementById('music-progress');
if (progress) progress.style.width = '0%';
if (state.musicPlayer.playing) {
stopMusicProgress();
setTimeout(startMusicProgress, 100);
}
}
function startMusicProgress() {
stopMusicProgress();
const track = state.musicPlayer.tracks[state.musicPlayer.currentTrack];
const progress = document.getElementById('music-progress');
const currentTimeEl = document.getElementById('current-time');
if (!progress || !currentTimeEl) return;
let currentSeconds = 0;
state.musicPlayer.progressInterval = setInterval(() => {
currentSeconds++;
if (currentSeconds >= track.duration) {
nextTrack();
return;
}
const percentage = (currentSeconds / track.duration) * 100;
progress.style.width = percentage + '%';
currentTimeEl.textContent = formatTime(currentSeconds);
updateVisualizer();
}, 1000);
}
function stopMusicProgress() {
if (state.musicPlayer.progressInterval) {
clearInterval(state.musicPlayer.progressInterval);
state.musicPlayer.progressInterval = null;
}
}
function seekMusic(event) {
if (state.musicPlayer.playing) {
const bar = event.currentTarget;
const rect = bar.getBoundingClientRect();
const clickX = event.clientX - rect.left;
const percentage = clickX / rect.width;
const track = state.musicPlayer.tracks[state.musicPlayer.currentTrack];
const newSeconds = Math.floor(percentage * track.duration);
const progress = document.getElementById('music-progress');
const currentTimeEl = document.getElementById('current-time');
if (progress && currentTimeEl) {
progress.style.width = (percentage * 100) + '%';
currentTimeEl.textContent = formatTime(newSeconds);
}
}
}
function setTrackVolume(value) {
state.settings.volume = value / 100;
saveSettings();
showNotification('info', '音量调整', '当前音量: ' + value + '%');
}
function createAudioVisualizer() {
const visualizer = document.getElementById('audio-visualizer');
if (!visualizer) return;
visualizer.innerHTML = '';
for (let i = 0; i < 20; i++) {
const bar = document.createElement('div');
bar.className = 'audio-bar';
bar.style.height = Math.random() * 20 + 5 + 'px';
visualizer.appendChild(bar);
}
}
function updateVisualizer() {
const visualizer = document.getElementById('audio-visualizer');
if (!visualizer) return;
if (state.musicPlayer.playing) {
const bars = visualizer.children;
for (let bar of bars) {
bar.style.height = Math.random() * 30 + 10 + 'px';
}
}
}
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = seconds % 60;
return mins + ':' + (secs < 10 ? '0' : '') + secs;
}
function openNotepad() {
if (state.apps['notepad']) {
activateWindow('notepad');
return;
}
const savedContent = localStorage.getItem('neon-os-notepad') || '';
const content = `
<div class="notepad">
<div class="notepad-toolbar">
<button class="notepad-btn" onclick="saveNotepad()">保存</button>
<button class="notepad-btn" onclick="clearNotepad()">清空</button>
<button class="notepad-btn" onclick="exportNotepad()">导出</button>
</div>
<textarea class="notepad-editor" id="notepad-editor" placeholder="输入您的笔记...">${savedContent}</textarea>
<div class="notepad-status" id="notepad-status">已保存至本地存储</div>
</div>
`;
createWindow('notepad', '便签', 'fas fa-sticky-note', content);
setTimeout(() => {
const editor = document.getElementById('notepad-editor');
if (editor) {
editor.addEventListener('input', () => {
localStorage.setItem('neon-os-notepad', editor.value);
updateNotepadStatus('已自动保存');
});
}
}, 100);
}
function saveNotepad() {
const editor = document.getElementById('notepad-editor');
if (editor) {
localStorage.setItem('neon-os-notepad', editor.value);
updateNotepadStatus('保存成功!');
showNotification('success', '便签', '笔记已保存');
}
}
function clearNotepad() {
const editor = document.getElementById('notepad-editor');
if (editor && confirm('确定要清空所有内容吗?')) {
editor.value = '';
localStorage.removeItem('neon-os-notepad');
updateNotepadStatus('已清空');
showNotification('success', '便签', '内容已清空');
}
}
function exportNotepad() {
const editor = document.getElementById('notepad-editor');
if (editor) {
const content = editor.value;
showNotification('info', '导出', '笔记内容已复制到剪贴板(模拟操作)');
navigator.clipboard.writeText(content).catch(() => {});
}
}
function updateNotepadStatus(message) {
const status = document.getElementById('notepad-status');
if (status) {
status.textContent = message;
setTimeout(() => {
status.textContent = '已保存至本地存储';
}, 2000);
}
}
function openMonitor() {
if (state.apps['monitor']) {
activateWindow('monitor');
return;
}
const content = `
<div class="monitor" id="monitor-content">
<div class="monitor-item">
<div class="monitor-item-title">CPU 使用率</div>
<div class="monitor-chart" id="cpu-chart"></div>
<div class="monitor-stats" id="cpu-stats">核心: 4 | 频率: 3.2GHz | 负载: 42%</div>
</div>
<div class="monitor-item">
<div class="monitor-item-title">内存使用</div>
<div class="monitor-chart" id="mem-chart"></div>
<div class="monitor-stats" id="mem-stats">总共: 16GB | 已用: 9.8GB | 可用: 6.2GB</div>
</div>
<div class="monitor-item">
<div class="monitor-item-title">磁盘 I/O</div>
<div class="monitor-chart" id="disk-chart"></div>
<div class="monitor-stats" id="disk-stats">读取: 12MB/s | 写入: 8MB/s</div>
</div>
<div class="monitor-item">
<div class="monitor-item-title">网络状态</div>
<div class="monitor-chart" id="network-chart"></div>
<div class="monitor-stats" id="network-stats">下载: 45Mbps | 上传: 12Mbps</div>
</div>
</div>
`;
createWindow('monitor', '系统监控', 'fas fa-chart-line', content);
setTimeout(() => startMonitorUpdate(), 500);
}
function startMonitorUpdate() {
stopMonitorCharts();
if (!state.apps['monitor']) return;
state.monitorInterval = setInterval(() => {
if (!state.apps['monitor']) {
stopMonitorCharts();
return;
}
updateMonitorChart('cpu-chart', Math.floor(Math.random() * 40) + 30, 'cpu-stats',
'核心: 4 | 频率: 3.2GHz | 负载: ' + (Math.floor(Math.random() * 20) + 30) + '%');
updateMonitorChart('mem-chart', Math.floor(Math.random() * 30) + 40, 'mem-stats',
'总共: 16GB | 已用: ' + (Math.random() * 4 + 9).toFixed(1) + 'GB | 可用: ' + (Math.random() * 2 + 4).toFixed(1) + 'GB');
updateMonitorChart('disk-chart', Math.floor(Math.random() * 30) + 20, 'disk-stats',
'读取: ' + (Math.floor(Math.random() * 20) + 5) + 'MB/s | 写入: ' + (Math.floor(Math.random() * 15) + 3) + 'MB/s');
updateMonitorChart('network-chart', Math.floor(Math.random() * 30) + 20, 'network-stats',
'下载: ' + (Math.floor(Math.random() * 50) + 10) + 'Mbps | 上传: ' + (Math.floor(Math.random() * 20) + 5) + 'Mbps');
}, 2000);
}
function updateMonitorChart(chartId, value, statsId, statsText) {
const chart = document.getElementById(chartId);
const stats = document.getElementById(statsId);
if (chart && stats) {
chart.innerHTML = '';
const barContainer = document.createElement('div');
barContainer.className = 'monitor-bar-chart';
for (let i = 0; i < 8; i++) {
const barItem = document.createElement('div');
barItem.className = 'monitor-bar-item';
const randomValue = Math.random() * 30 + value - 15;
barItem.style.height = Math.max(5, randomValue) + '%';
barContainer.appendChild(barItem);
}
chart.appendChild(barContainer);
if (stats) {
stats.textContent = statsText;
}
}
}
function stopMonitorCharts() {
if (state.monitorInterval) {
clearInterval(state.monitorInterval);
state.monitorInterval = null;
}
}
function openAbout() {
if (state.apps['about']) {
activateWindow('about');
return;
}
const content = `
<div style="padding: 20px; line-height: 1.6; color: var(--neon-blue);">
<div style="text-align: center; margin-bottom: 20px;">
<h2 style="color: var(--neon-pink); font-family: 'Orbitron', sans-serif; margin-bottom: 10px;">NEON-OS</h2>
<p style="color: var(--neon-cyan);">赛博朋克未来操作系统</p>
</div>
<div style="background: rgba(0,0,0,0.3); padding: 15px; border-radius: 8px; margin-bottom: 15px;">
<h3 style="color: var(--neon-pink); margin-bottom: 8px;">系统规格</h3>
<p>版本: <span class="highlight">1.0.0</span></p>
<p>架构: WebAssembly/JS</p>
<p>构建日期: 2024</p>
</div>
<div style="background: rgba(0,0,0,0.3); padding: 15px; border-radius: 8px; margin-bottom: 15px;">
<h3 style="color: var(--neon-pink); margin-bottom: 8px;">功能特性</h3>
<ul style="margin-left: 20px;">
<li>完整的窗口管理系统</li>
<li>终端模拟器支持Linux命令</li>
<li>多媒体音乐播放器</li>
<li>系统监控与性能分析</li>
<li>本地化数据持久化</li>
<li>赛博朋克主题UI</li>
</ul>
</div>
<div style="text-align: center; margin-top: 20px; padding-top: 20px; border-top: 1px solid rgba(5, 217, 232, 0.2);">
<p style="color: var(--neon-purple);">© 2024 NEON-OS Project | 全栈工程示例</p>
<p style="color: var(--neon-cyan); font-size: 0.8rem; margin-top: 8px;">右键桌面探索更多功能</p>
</div>
</div>
`;
createWindow('about', '关于系统', 'fas fa-info-circle', content);
}
// 系统函数
function toggleStartMenu() {
const menu = document.getElementById('start-menu');
if (menu.style.display === 'block') {
menu.style.display = 'none';
} else {
menu.style.display = 'block';
setTimeout(() => {
document.addEventListener('click', closeStartMenuOnce);
}, 100);
}
}
function closeStartMenuOnce(e) {
const menu = document.getElementById('start-menu');
const startBtn = document.querySelector('.taskbar-start');
if (menu && menu.style.display === 'block' &&
!menu.contains(e.target) && !startBtn.contains(e.target)) {
menu.style.display = 'none';
document.removeEventListener('click', closeStartMenuOnce);
}
}
function toggleVolume() {
showNotification('info', '音量', '当前音量: ' + Math.round(state.settings.volume * 100) + '%');
}
function showNotification(type, title, message) {
if (!state.settings.notifications) return;
const area = document.getElementById('notification-area');
const notification = document.createElement('div');
notification.className = 'notification ' + type;
const icons = {
success: 'fa-check-circle',
error: 'fa-times-circle',
warning: 'fa-exclamation-triangle',
info: 'fa-info-circle'
};
notification.innerHTML = `
<div class="notification-header">
<div class="notification-title"><i class="fas ${icons[type]}"></i> ${title}</div>
<div class="notification-close" onclick="this.parentElement.parentElement.remove()">
<i class="fas fa-times"></i>
</div>
</div>
<div class="notification-body">${message}</div>
`;
area.appendChild(notification);
setTimeout(() => {
if (notification.parentElement) {
notification.style.opacity = '0';
notification.style.transform = 'translateX(100%)';
setTimeout(() => notification.remove(), 300);
}
}, 4000);
}
function closeContextMenuOnce(e) {
const contextMenu = document.getElementById('context-menu');
if (contextMenu && contextMenu.style.display === 'block' && !contextMenu.contains(e.target)) {
contextMenu.style.display = 'none';
document.removeEventListener('click', closeContextMenuOnce);
}
}
// 桌面右键菜单
document.addEventListener('contextmenu', (e) => {
const desktop = document.getElementById('desktop');
const contextMenu = document.getElementById('context-menu');
// 确保是在桌面上的右键
if (!desktop || desktop.style.display === 'none') return;
if (desktop.contains(e.target)) {
e.preventDefault();
contextMenu.style.display = 'block';
contextMenu.style.left = e.pageX + 'px';
contextMenu.style.top = e.pageY + 'px';
setTimeout(() => {
document.addEventListener('click', closeContextMenuOnce);
}, 100);
}
});
function refreshDesktop() {
if (state.apps['file-manager']) {
renderFileManager();
}
showNotification('success', '刷新', '桌面已刷新');
}
// 主题和壁纸应用
function applyTheme() {
const root = document.documentElement;
const theme = state.settings.theme;
const themes = {
cyberpunk: {
neonPink: '#ff2a6d',
neonBlue: '#05d9e8',
neonPurple: '#d100d1',
neonCyan: '#00ff9f',
darkBg: '#0d0d16'
},
retro: {
neonPink: '#ff7700',
neonBlue: '#00ff88',
neonPurple: '#ff00aa',
neonCyan: '#ffff00',
darkBg: '#1a1a2e'
},
minimal: {
neonPink: '#00ff88',
neonBlue: '#00ccff',
neonPurple: '#aa88ff',
neonCyan: '#ffffff',
darkBg: '#0a0a0a'
},
dark: {
neonPink: '#bb0044',
neonBlue: '#0088cc',
neonPurple: '#6600cc',
neonCyan: '#00cc88',
darkBg: '#000000'
},
light: {
neonPink: '#cc0066',
neonBlue: '#0066cc',
neonPurple: '#6600cc',
neonCyan: '#009966',
darkBg: '#f0f0f0'
}
};
const selectedTheme = themes[theme] || themes.cyberpunk;
root.style.setProperty('--neon-pink', selectedTheme.neonPink);
root.style.setProperty('--neon-blue', selectedTheme.neonBlue);
root.style.setProperty('--neon-purple', selectedTheme.neonPurple);
root.style.setProperty('--neon-cyan', selectedTheme.neonCyan);
root.style.setProperty('--dark-bg', selectedTheme.darkBg);
if (theme === 'light') {
root.style.setProperty('--glass-bg', 'rgba(255, 255, 255, 0.8)');
root.style.setProperty('--glass-border', 'rgba(0, 102, 204, 0.3)');
} else {
root.style.setProperty('--glass-bg', 'rgba(13, 13, 22, 0.7)');
root.style.setProperty('--glass-border', 'rgba(5, 217, 232, 0.3)');
}
}
function applyWallpaper() {
const bg = document.querySelector('.desktop-bg');
const wallpaper = state.settings.wallpaper;
if (!bg) return;
let background = '';
switch(wallpaper) {
case 'neon':
background = `linear-gradient(135deg, rgba(255, 42, 109, 0.1), rgba(5, 217, 232, 0.1)), radial-gradient(circle at 20% 50%, rgba(255, 42, 109, 0.1), transparent 50%), radial-gradient(circle at 80% 80%, rgba(5, 217, 232, 0.1), transparent 50%)`;
break;
case 'grid':
background = `linear-gradient(rgba(0, 255, 159, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 255, 159, 0.05) 1px, transparent 1px), repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0, 255, 159, 0.03) 2px, rgba(0, 255, 159, 0.03) 3px), repeating-linear-gradient(90deg, transparent, transparent 2px, rgba(0, 255, 159, 0.03) 2px, rgba(0, 255, 159, 0.03) 3px)`;
break;
case 'city':
background = `linear-gradient(180deg, rgba(13, 13, 22, 0.7), rgba(13, 13, 22, 0.3)), repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(255, 42, 109, 0.1) 2px, rgba(255, 42, 109, 0.1) 3px)`;
break;
case 'matrix':
background = `linear-gradient(rgba(0, 255, 159, 0.02) 2px, transparent 2px), linear-gradient(90deg, rgba(0, 255, 159, 0.02) 2px, transparent 2px)`;
break;
default:
background = `linear-gradient(rgba(13, 13, 22, 0.9), rgba(13, 13, 22, 0.7)), repeating-linear-gradient(0deg, transparent, transparent 2px, var(--grid-color) 2px, var(--grid-color) 3px), repeating-linear-gradient(90deg, transparent, transparent 2px, var(--grid-color) 2px, var(--grid-color) 3px)`;
}
bg.style.background = background;
}
function saveSettings() {
localStorage.setItem('neon-os-settings', JSON.stringify(state.settings));
}
// 矩阵雨特效
function startMatrixRain() {
const canvas = document.getElementById('matrix-canvas');
const ctx = canvas.getContext('2d');
canvas.style.display = 'block';
state.matrixRunning = true;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const cols = Math.floor(canvas.width / 20);
const drops = [];
const chars = '01abcdef0123456789@$%&*';
for (let i = 0; i < cols; i++) {
drops[i] = 1;
}
function draw() {
if (!state.matrixRunning) {
canvas.style.display = 'none';
return;
}
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#00ff9f';
ctx.font = '16px monospace';
for (let i = 0; i < drops.length; i++) {
const text = chars.charAt(Math.floor(Math.random() * chars.length));
ctx.fillText(text, i * 20, drops[i] * 20);
if (drops[i] * 20 > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
requestAnimationFrame(draw);
}
draw();
const exitHandler = () => {
state.matrixRunning = false;
document.removeEventListener('keydown', exitHandler);
document.removeEventListener('click', exitHandler);
};
setTimeout(() => {
document.addEventListener('keydown', exitHandler);
document.addEventListener('click', exitHandler);
}, 100);
}
// 系统操作
function rebootSystem() {
showNotification('warning', '系统重启', '正在重启系统...');
setTimeout(() => {
location.reload();
}, 2000);
}
function logout() {
showNotification('info', '切换用户', '正在切换用户...');
Object.keys(state.apps).forEach(appId => closeWindow(appId));
state.currentDirectory = [];
setTimeout(() => {
document.getElementById('desktop').style.display = 'none';
document.getElementById('start-menu').style.display = 'none';
showLockScreen();
}, 1000);
}
function shutdown() {
showNotification('error', '关机', '系统正在关闭...');
const desktop = document.getElementById('desktop');
if (desktop) desktop.style.opacity = '0';
setTimeout(() => {
document.body.innerHTML = `
<div style="display: flex; justify-content: center; align-items: center; height: 100vh; background: #000; color: var(--neon-pink); font-family: 'Orbitron', sans-serif; font-size: 2rem;">
系统已关机
</div>
`;
}, 2000);
}
// 键盘快捷键
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.altKey && e.key === 't') {
e.preventDefault();
openTerminal();
}
if (e.ctrlKey && e.altKey && e.key === 'w') {
e.preventDefault();
let topZIndex = 0;
let topAppId = null;
Object.entries(state.apps).forEach(([appId, app]) => {
const zIndex = parseInt(app.element.style.zIndex);
if (zIndex > topZIndex && !app.minimized) {
topZIndex = zIndex;
topAppId = appId;
}
});
if (topAppId) {
closeWindow(topAppId);
}
}
if (e.ctrlKey && e.altKey && e.key === 'm') {
e.preventDefault();
let topZIndex = 0;
let topAppId = null;
Object.entries(state.apps).forEach(([appId, app]) => {
const zIndex = parseInt(app.element.style.zIndex);
if (zIndex > topZIndex && !app.minimized) {
topZIndex = zIndex;
topAppId = appId;
}
});
if (topAppId) {
minimizeWindow(topAppId);
}
}
if (e.ctrlKey && e.altKey && e.key === 'e') {
e.preventDefault();
openApp('file-manager');
}
});
// 窗口点击事件(激活窗口)
document.addEventListener('click', (e) => {
const windowElement = e.target.closest('.window');
if (windowElement && !e.target.closest('.window-control')) {
const appId = windowElement.id.replace('window-', '');
activateWindow(appId);
}
});
// 响应式处理
window.addEventListener('resize', () => {
Object.values(state.apps).forEach(app => {
if (!app.maximized && !app.minimized) {
const rect = app.element.getBoundingClientRect();
if (rect.left > window.innerWidth || rect.top > window.innerHeight) {
app.element.style.left = '50px';
app.element.style.top = '50px';
}
}
});
const matrixCanvas = document.getElementById('matrix-canvas');
if (matrixCanvas && matrixCanvas.style.display !== 'none') {
matrixCanvas.width = window.innerWidth;
matrixCanvas.height = window.innerHeight;
}
});
// 系统初始化
document.addEventListener('DOMContentLoaded', () => {
console.log('[INIT] DOM加载完成开始初始化系统');
initSystem();
setTimeout(() => {
applyTheme();
applyWallpaper();
}, 100);
});
</script>
</body>
</html>