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

2587 lines
98 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>