注:其中使用的关键词可以直接提供给AI,如果操作有区别,请根据您使用的AI提供步骤为准

环境准备:

首先需要下载好cmakenode.js (建议 v14.0 以上)和python

其次需要您打开乐青映射https://www.locyanfrp.cn/的官网下载他的启动器kairo,或者您可以选择下载他的纯净版客户端Frpc,都是可以的

Web前端的开发和Node.js后端迅速开发,AI的快速应用(我使用的是gemini开发的)

注:不一定要使用gemini进行开发,您有多种选择例如codex,cursor等等都可以帮助您进行快速开发

gemini开发教程

第一步关键词说明(如果您使用的是codex,cursor这种有agent功能的ai会开发的更加快速)

我现在需要写一个智能头盔管理系统,框架采用前后端分离的结构,后端使用nodejs,所有的接口需要清晰分明,前端不采用任何框架,单纯使用html,js以及css需要单出生成文件,不要全部放在html里面,首先帮我实现第一步,搭建一个websocket服务器,前端可以自行设置服务器地址端口进行链接,服务器默认逻辑是接收到数据后,转发数据

1.文件创建(这个只是示例,内部文件的命名和位置可根据自己的喜好进行修改)

helmet-system/           # 项目根目录
├── package.json         # 项目配置文件
├── node_modules/        # 依赖库
├── backend/             # 后端代码
│   └── server.js        # 核心服务器文件
└── frontend/            # 前端代码
    ├── index.html       # 页面结构
    ├── style.css        # 样式表
    └── script.js        # 交互逻辑

2.打开文件,在文件路径使用cmd(下方是示例)

3.下载初始化与依赖(这个是命令行代码,请一句一句输入)
npm init -y          # 初始化项目
npm install ws       # 安装 WebSocket 库 (唯一的外部依赖)
4.服务器启动(请在把后面修改了UI的代码复制后再开启服务器进行测试)-(这个是命令行代码,请一句一句输入)
node backend/server.js

效果图(这个只是示例,不同的ai会有不同的网页结构构筑,请以自己的代码为准)

UI的美化以及将前端部署至网页

第二步关键词

前端需要部署到网页上 比如说127.0.0.1 不能直接以静态文件进行打开

第三步关键词

完全重构这个系统UI 不要改动功能业务代码 UI需要符合现代化设计 符合苹果前端设计理念 系统交互需要流畅 动效过渡需要细腻 内容需要丰富

package.json
{
  "name": "helmet-system",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "ws": "^8.19.0"
  }
}
backend/server.js
/**
 * backend/server.js
 * 极简版服务器 - 只使用 ws 和原生模块
 * 绝对不包含 document 等前端代码
 */
const http = require('http');
const fs = require('fs');
const path = require('path');
const WebSocket = require('ws');

const PORT = 8080;

// 文件类型映射
const MIME_TYPES = {
    '.html': 'text/html',
    '.css': 'text/css',
    '.js': 'text/javascript',
    '.json': 'application/json'
};

// 1. 创建 HTTP 服务器 (负责让浏览器能看到网页)
const server = http.createServer((req, res) => {
    // 默认访问 index.html
    let filePath = req.url === '/' ? 'index.html' : req.url;
    
    // 指向 ../frontend 文件夹
    const fullPath = path.join(__dirname, '../frontend', filePath);

    const extname = path.extname(fullPath);
    const contentType = MIME_TYPES[extname] || 'text/plain';

    fs.readFile(fullPath, (err, content) => {
        if (err) {
            if (err.code === 'ENOENT') {
                res.writeHead(404);
                res.end('404 Not Found');
            } else {
                res.writeHead(500);
                res.end(`Server Error: ${err.code}`);
            }
        } else {
            res.writeHead(200, { 'Content-Type': contentType });
            res.end(content, 'utf-8');
        }
    });
});

// 2. 创建 WebSocket 服务器 (负责数据实时转发)
const wss = new WebSocket.Server({ server });

wss.on('connection', (ws, req) => {
    const ip = req.socket.remoteAddress;
    console.log(`[WebSocket] 新连接: ${ip}`);

    ws.on('message', (message) => {
        // 收到消息,直接转发给其他人
        const msgString = message.toString();
        console.log(`[转发数据] ${msgString}`);
        
        wss.clients.forEach((client) => {
            if (client !== ws && client.readyState === WebSocket.OPEN) {
                client.send(msgString);
            }
        });
    });
});

// 3. 启动
server.listen(PORT, () => {
    console.log(`-----------------------------------`);
    console.log(`服务器已启动!`);
    console.log(`请在浏览器打开: http://127.0.0.1:${PORT}`);
    console.log(`-----------------------------------`);
});
frontend/index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>iHelmet 智能终端</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    
    <div class="ambient-light"></div>

    <div class="app-container">
        <nav class="sidebar glass">
            <div class="brand">
                <div class="logo-icon"></div>
                <span>iHelmet Pro</span>
            </div>
            
            <ul class="menu">
                <li class="active">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
                    监控台
                </li>
                <li>
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
                    设备管理
                </li>
            </ul>

            <div class="user-profile">
                <div class="avatar">Admin</div>
                <div class="info">
                    <span class="name">系统管理员</span>
                    <span class="role">在线</span>
                </div>
            </div>
        </nav>

        <main class="dashboard">
            <header class="glass-header">
                <h1>实时数据中心</h1>
                <div class="server-status">
                    <div id="statusDot" class="status-dot offline"></div>
                    <span id="statusText">未连接服务器</span>
                </div>
            </header>

            <div class="content-grid">
                <div class="col-left">
                    <section class="card glass-card">
                        <div class="card-header">
                            <h3>服务器连接</h3>
                        </div>
                        <div class="card-body">
                            <div class="input-group">
                                <label>Server Address</label>
                                <input type="text" id="serverIp" placeholder="127.0.0.1" class="ios-input">
                            </div>
                            <div class="input-group">
                                <label>Port</label>
                                <input type="number" id="serverPort" placeholder="8080" class="ios-input">
                            </div>
                            <button id="btnConnect" class="ios-btn btn-primary">
                                <span>连接系统</span>
                            </button>
                        </div>
                    </section>

                    <section class="card glass-card">
                        <div class="card-header">
                            <h3>模拟传感器</h3>
                        </div>
                        <div class="card-body">
                            <textarea id="msgInput" class="ios-textarea" placeholder="{ 'gps': [116.3, 39.9], 'bpm': 85 }"></textarea>
                            <button id="btnSend" class="ios-btn btn-success" disabled>
                                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon></svg>
                                发送数据
                            </button>
                        </div>
                    </section>
                </div>

                <div class="col-right">
                    <section class="card glass-card full-height">
                        <div class="card-header flex-header">
                            <h3>数据流监控</h3>
                            <button id="btnClear" class="text-btn">清除日志</button>
                        </div>
                        <div id="logArea" class="chat-container">
                            <div class="system-msg">系统准备就绪,等待连接...</div>
                        </div>
                    </section>
                </div>
            </div>
        </main>
    </div>

    <script src="script.js"></script>
</body>
</html>
frontend/style.css
/* frontend/style.css */
:root {
    --bg-color: #fbfbfd;
    --text-main: #1d1d1f;
    --text-secondary: #86868b;
    --accent-blue: #0071e3;
    --accent-green: #34c759;
    --accent-red: #ff3b30;
    --glass-bg: rgba(255, 255, 255, 0.75);
    --glass-border: rgba(255, 255, 255, 0.4);
    --shadow-soft: 0 8px 30px rgba(0, 0, 0, 0.04);
    --radius-lg: 20px;
    --radius-md: 12px;
}

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif;
    background-color: #f5f5f7;
    color: var(--text-main);
    overflow: hidden;
    height: 100vh;
}

/* 动态背景光效 */
.ambient-light {
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(circle at 50% 50%, #e0f0ff 0%, #f5f5f7 40%);
    z-index: -1;
    animation: pulseLight 10s infinite alternate;
}

@keyframes pulseLight {
    0% { transform: scale(1); }
    100% { transform: scale(1.1); }
}

.app-container {
    display: flex;
    height: 100vh;
    padding: 20px;
    box-sizing: border-box;
    gap: 20px;
}

/* --- Sidebar --- */
.sidebar {
    width: 240px;
    background: var(--glass-bg);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-radius: var(--radius-lg);
    border: 1px solid var(--glass-border);
    padding: 30px 20px;
    display: flex;
    flex-direction: column;
    box-shadow: var(--shadow-soft);
}

.brand {
    font-size: 20px;
    font-weight: 700;
    margin-bottom: 40px;
    display: flex;
    align-items: center;
    gap: 10px;
}

.menu {
    list-style: none;
    padding: 0;
    flex: 1;
}

.menu li {
    padding: 12px 16px;
    margin-bottom: 8px;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    cursor: pointer;
    transition: all 0.3s ease;
    display: flex;
    align-items: center;
    gap: 12px;
    font-weight: 500;
}

.menu li svg { width: 20px; height: 20px; }

.menu li.active, .menu li:hover {
    background: white;
    color: var(--accent-blue);
    box-shadow: 0 4px 12px rgba(0,0,0,0.05);
}

.user-profile {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-top: 20px;
    border-top: 1px solid rgba(0,0,0,0.05);
}

.avatar {
    width: 40px;
    height: 40px;
    background: linear-gradient(135deg, #0071e3, #42a5f5);
    border-radius: 50%;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: bold;
}

.info .name { display: block; font-size: 14px; font-weight: 600; }
.info .role { font-size: 12px; color: var(--accent-green); }

/* --- Dashboard --- */
.dashboard {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.glass-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 10px;
}

.server-status {
    display: flex;
    align-items: center;
    gap: 8px;
    background: white;
    padding: 6px 12px;
    border-radius: 20px;
    font-size: 13px;
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.status-dot { width: 8px; height: 8px; border-radius: 50%; background: #ccc; }
.status-dot.online { background: var(--accent-green); box-shadow: 0 0 8px var(--accent-green); }
.status-dot.offline { background: #ccc; }
.status-dot.error { background: var(--accent-red); }

.content-grid {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 20px;
    height: 100%;
    overflow: hidden; /* 防止溢出 */
}

/* --- Cards --- */
.glass-card {
    background: var(--glass-bg);
    backdrop-filter: blur(20px);
    border-radius: var(--radius-lg);
    border: 1px solid var(--glass-border);
    padding: 24px;
    box-shadow: var(--shadow-soft);
    display: flex;
    flex-direction: column;
    transition: transform 0.2s;
}

.col-right .glass-card {
    height: calc(100vh - 120px); /* 确保高度填满 */
}

.card-header h3 {
    margin: 0 0 20px 0;
    font-size: 16px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.flex-header { display: flex; justify-content: space-between; align-items: center; }

/* --- Inputs & Buttons --- */
.input-group { margin-bottom: 15px; }
.input-group label { display: block; font-size: 12px; color: var(--text-secondary); margin-bottom: 5px; font-weight: 600; }

.ios-input, .ios-textarea {
    width: 100%;
    padding: 12px;
    border: none;
    background: white;
    border-radius: var(--radius-md);
    font-size: 14px;
    color: var(--text-main);
    box-sizing: border-box;
    transition: box-shadow 0.2s;
    font-family: inherit;
}

.ios-textarea { height: 80px; resize: none; }

.ios-input:focus, .ios-textarea:focus {
    outline: none;
    box-shadow: 0 0 0 2px var(--accent-blue);
}

.ios-btn {
    width: 100%;
    padding: 14px;
    border: none;
    border-radius: var(--radius-md);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    color: white;
}

.btn-primary { background: var(--accent-blue); }
.btn-primary:hover { background: #0077ED; transform: scale(1.02); }
.btn-primary:active { transform: scale(0.98); }

.btn-success { background: var(--accent-green); }
.btn-success:disabled { background: #ccc; cursor: not-allowed; opacity: 0.6; }

.text-btn { background: none; border: none; color: var(--accent-blue); cursor: pointer; font-size: 13px; }

/* --- Chat Style Log --- */
.chat-container {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.system-msg {
    text-align: center;
    font-size: 12px;
    color: var(--text-secondary);
    margin: 10px 0;
}

.msg-bubble {
    max-width: 80%;
    padding: 10px 16px;
    border-radius: 18px;
    font-size: 14px;
    line-height: 1.4;
    position: relative;
    animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    word-break: break-all;
}

@keyframes popIn {
    from { opacity: 0; transform: translateY(10px) scale(0.9); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

.msg-sent {
    align-self: flex-end;
    background: var(--accent-blue);
    color: white;
    border-bottom-right-radius: 4px;
}

.msg-received {
    align-self: flex-start;
    background: white;
    color: var(--text-main);
    border-bottom-left-radius: 4px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}

.time-stamp {
    font-size: 10px;
    opacity: 0.7;
    margin-top: 4px;
    display: block;
    text-align: right;
}
frontend/script.js
/* frontend/script.js */

let ws = null;

// DOM 元素获取 (保持ID不变,适配新UI)
const inputs = {
    ip: document.getElementById('serverIp'),
    port: document.getElementById('serverPort'),
    msg: document.getElementById('msgInput')
};

const btnConnect = document.getElementById('btnConnect');
const btnSend = document.getElementById('btnSend');
const btnClear = document.getElementById('btnClear'); // 新增清除按钮
const logArea = document.getElementById('logArea');
const statusText = document.getElementById('statusText');
const statusDot = document.getElementById('statusDot');

// 自动填充当前地址
window.onload = () => {
    inputs.ip.value = window.location.hostname;
    inputs.port.value = window.location.port;
};

// --- 事件监听 ---

btnConnect.addEventListener('click', toggleConnection);
btnSend.addEventListener('click', sendMessage);
btnClear.addEventListener('click', () => {
    logArea.innerHTML = '<div class="system-msg">日志已清除</div>';
});

// --- 核心逻辑 ---

function toggleConnection() {
    if (ws) {
        // 如果已连接,则断开
        ws.close();
        return;
    }

    const ip = inputs.ip.value;
    const port = inputs.port.value;
    const url = `ws://${ip}:${port}`;

    logToSystem(`正在连接到服务器...`);

    try {
        ws = new WebSocket(url);

        ws.onopen = () => {
            updateUIState(true);
            logToSystem('连接成功');
        };

        ws.onmessage = (event) => {
            logMessage(event.data, 'received');
        };

        ws.onclose = () => {
            updateUIState(false);
            ws = null;
            logToSystem('服务器连接已断开');
        };

        ws.onerror = () => {
            updateUIState(false);
            statusDot.className = 'status-dot error';
            statusText.innerText = '连接错误';
            logToSystem('连接发生错误,请检查网络');
        };

    } catch (e) {
        logToSystem('URL 格式错误');
    }
}

function sendMessage() {
    if (ws && ws.readyState === WebSocket.OPEN) {
        const msg = inputs.msg.value;
        if (!msg) return;
        
        ws.send(msg);
        logMessage(msg, 'sent');
    }
}

// --- UI 渲染函数 (这里是改动最大的地方,为了漂亮) ---

function updateUIState(isConnected) {
    if (isConnected) {
        statusText.innerText = 'System Online';
        statusDot.className = 'status-dot online';
        btnConnect.innerHTML = '<span>断开连接</span>';
        btnConnect.style.background = '#ff3b30'; // 红色
        btnSend.disabled = false;
        inputs.ip.disabled = true;
        inputs.port.disabled = true;
    } else {
        statusText.innerText = '未连接服务器';
        statusDot.className = 'status-dot offline';
        btnConnect.innerHTML = '<span>连接系统</span>';
        btnConnect.style.background = ''; // 恢复默认蓝色
        btnSend.disabled = true;
        inputs.ip.disabled = false;
        inputs.port.disabled = false;
    }
}

// 生成聊天气泡风格的消息
function logMessage(text, type) {
    const div = document.createElement('div');
    const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
    
    div.className = `msg-bubble ${type === 'sent' ? 'msg-sent' : 'msg-received'}`;
    div.innerHTML = `
        ${text}
        <span class="time-stamp">${time}</span>
    `;
    
    logArea.appendChild(div);
    scrollToBottom();
}

// 生成系统提示消息
function logToSystem(text) {
    const div = document.createElement('div');
    div.className = 'system-msg';
    div.innerText = text;
    logArea.appendChild(div);
    scrollToBottom();
}

function scrollToBottom() {
    logArea.scrollTo({
        top: logArea.scrollHeight,
        behavior: 'smooth'
    });
}

效果图如下

恭喜您现在已经完成了内网的访问

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐