diff --git a/miner/.vscode/settings.json b/miner/.vscode/settings.json
new file mode 100644
index 0000000..6f3a291
--- /dev/null
+++ b/miner/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "liveServer.settings.port": 5501
+}
\ No newline at end of file
diff --git a/miner/css/base.css b/miner/css/base.css
new file mode 100644
index 0000000..7c1f859
--- /dev/null
+++ b/miner/css/base.css
@@ -0,0 +1,70 @@
+/* 所有标签的内外边距清零 */
+* {
+ margin: 0px;
+ padding: 0px;
+ /* css3盒子模型 */
+ box-sizing: border-box;
+ font-family:DFKai-SB;
+}
+/* em 和 i 斜体的文字不倾斜 */
+em,
+i {
+ font-style: normal
+}
+/* 去掉li 的小圆点 */
+/* li {
+ list-style: none
+} */
+/* ul{
+ list-style: none;
+} */
+
+img {
+ /* border 0 照顾低版本浏览器 如果 图片外面包含了链接会有边框的问题 */
+ border: 0;
+ /* 取消图片底侧有空白缝隙的问题 */
+ vertical-align: middle;
+}
+
+button {
+ /* 当我们鼠标经过button 按钮的时候,鼠标变成小手 */
+ cursor: pointer
+}
+
+a {
+ color: #666;
+ text-decoration: none
+}
+
+a:hover {
+ color: #c81623
+}
+
+button,
+input {
+ /* "\5B8B\4F53" 就是宋体的意思 这样浏览器兼容性比较好 */
+ font-family: Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\5B8B\4F53", sans-serif;
+ /* 默认有灰色边框我们需要手动去掉 */
+}
+
+body {
+ /* CSS3 抗锯齿形 让文字显示的更加清晰 */
+ -webkit-font-smoothing: antialiased;
+ /* background-color: #fff; */
+ /* font: 12px/1.5 Microsoft YaHei, Heiti SC, tahoma, arial, Hiragino Sans GB, "\5B8B\4F53", sans-serif; */
+ /* color: #666 */
+}
+
+.hide,
+.none {
+ display: none
+}
+/* 清除浮动 */
+.clearfix::after {
+ visibility: hidden;
+ clear: both;
+ display: block;
+ content: ".";
+ height: 0
+}
+
diff --git a/miner/css/index.css b/miner/css/index.css
new file mode 100644
index 0000000..cf0c9b3
--- /dev/null
+++ b/miner/css/index.css
@@ -0,0 +1,398 @@
+
+ body {
+ margin: 0;
+ font-family: 'Segoe UI', 'PingFang SC', 'Hiragino Sans', Arial, sans-serif;
+ background: #f3f7f9;
+ color: #222;
+ }
+ .container { display: flex; height: 100vh; }
+
+/* 修改侧边栏相关样式 */
+.sidebar {
+ width: 280px;
+ background: #2A58AE; /* 更深的蓝色背景 */
+ color: #fff;
+ display: flex;
+ flex-direction: column;
+ padding: 0;
+
+ }
+
+ .sidebar-logo {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ height: 180px;
+ }
+
+ .sidebar-logo img {
+ width: 120px;
+ height: auto;
+ }
+
+
+
+ .sidebar-menu ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ }
+
+/* 主菜单项样式 */
+.sidebar-menu > ul > li {
+ width: 100%;
+ padding: 0;
+ cursor: pointer;
+ font-size: 16px;
+ position: relative;
+ margin-bottom: 0; /* 移除底部间距 */
+ /* background: palegoldenrod; */
+ padding: 20px 0px;
+ padding-left: 50px;
+ min-height: 50px;
+
+ }
+
+ .sidebar-menu > ul > li > a {
+
+ display: block;
+ color: #9EA5AD;
+ text-decoration: none;
+ font-weight: 600; /* 稍微加粗 */
+ font-size: 1.3vw;
+ }
+
+
+ /* 子菜单项活动状态下的链接颜色 */
+.sidebar-submenu li.active > a {
+ color: #ffffff; /* 纯白色 */
+ }
+
+ /* 活动菜单项的竖线 */
+ /* .sidebar-menu > ul > li.active::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100%;
+ width: 4px;
+ background: #fff;
+ } */
+
+ .sidebar-menu > ul > li.active{
+ border-left: 8px solid rgba(255,255,255,0.8);
+ background: #1D4791;
+ }
+
+ /* 主菜单hover效果 */
+ .sidebar-menu > ul > li:hover > a {
+ color: #ffffff;
+ }
+
+ .sidebar-menu > ul > li:hover {
+ background: rgba(255, 255, 255, 0.1);
+ }
+
+
+
+
+/* 子菜单样式 */
+.sidebar-submenu {
+ padding-left: 0;
+ margin-left: 42px; /* 调整左边距 */
+ position: relative;
+ margin-bottom: 12px; /* 增加底部间距 */
+ margin-top: 30px;
+ background: palegoldenrod;
+ }
+
+/* 子菜单的垂直连接线 */
+.sidebar-submenu::before {
+ content: '';
+ position: absolute;
+ left: -20px; /* 调整位置 */
+ top: 0;
+ height: 100%;
+ width: 1px;
+ background: rgba(255, 255, 255, 0.4); /* 略微调亮 */
+ }
+
+
+ .sidebar-submenu li {
+ padding: 6px 16px ; /* 减少上下padding */
+ font-size: 14px ;
+ position: relative;
+ margin-bottom: 2px; /* 减少项目间距 */
+ color: rgba(255, 255, 255, 0.6); /* 默认颜色 */
+ transition: color 0.2s;
+ min-height: 50px;
+
+
+ }
+ .sidebar-submenu li a{
+ color: #9EA5AD;
+ font-size: 1.3vw;
+ font-weight: 600;
+
+ }
+/* 子菜单项的水平连接线 */
+.sidebar-submenu li::before {
+ content: '';
+ position: absolute;
+ left: -20px; /* 位置调整 */
+ top: 50%;
+ width: 20px; /* 调整水平线长度 */
+ height: 1px;
+ background: rgba(255, 255, 255, 0.4); /* 保持一致性 */
+ }
+
+/* 活动子菜单项样式 */
+.sidebar-submenu li.active {
+ color: #ffffff; /* 全白 */
+ background: none !important;
+ border: none !important;
+ }
+
+
+
+ /* 主菜单项活动状态下的链接颜色 */
+.sidebar-menu > ul > li.active > a {
+ color: #ffffff; /* 纯白色 */
+ }
+ /* 非活动子菜单项样式 */
+.sidebar-submenu li:not(.active) {
+ color: rgba(255, 255, 255, 0.6); /* 更明显的透明度 */
+ }
+
+ /* 禁用的菜单项 */
+ .sidebar-submenu li[style*="opacity"] {
+ opacity: 0.4 !important;
+ color: rgba(255, 255, 255, 0.5);
+ }
+
+ .sidebar-submenu li.active::before {
+ background: #fff;
+ }
+
+
+ /* 移除之前的hover效果 */
+ .sidebar-menu li:hover,
+ .sidebar-submenu li:hover {
+ background: none;
+ border-left: none;
+ text-decoration: none;
+ }
+
+
+
+ /* 子菜单hover效果 */
+ .sidebar-submenu li:not([style*="opacity"]):hover {
+ opacity: 1;
+ }
+/* ----------------------------- */
+
+/* 添加重启按钮样式 */
+.restart-btn {
+ background-color: #f56c6c;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ padding: 7px 15px;
+ font-size: 14px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ transition: background-color 0.3s;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+ }
+
+ .restart-btn:hover {
+ background-color: #e64242;
+ }
+
+ .restart-btn:focus {
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.3);
+ }
+ /* ---------------- */
+
+
+
+
+
+
+
+
+
+
+
+ .main {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ background: #eaf1f5;
+ }
+ .header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: #fff;
+ padding: 18px 36px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.03);
+ }
+ .header-user {
+ display: flex;
+ align-items: center;
+ font-size: 18px;
+ color: #204080;
+ font-weight: 600;
+ }
+ .header-user .icon {
+ background: #e3eafc;
+ border-radius: 50%;
+ width: 36px;
+ height: 36px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 10px;
+ font-size: 20px;
+ }
+
+ .summary-row {
+ display: flex;
+ gap: 24px;
+ margin: 32px 0 0 0;
+ }
+ .summary-card {
+ background: #fff;
+ border-radius: 14px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.04);
+ flex: 1;
+ padding: 28px 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-width: 0;
+ }
+ .summary-card .label {
+ color: #888;
+ font-weight: 600;
+ margin-bottom: 8px;
+ }
+ .summary-card .value {
+ font-size: 2.1rem;
+ font-weight: bold;
+ color: #204080;
+ }
+ .summary-card .unit {
+ font-size: 13px;
+ color: #bbb;
+ margin-top: 2px;
+ }
+ .fan-row {
+ display: flex;
+ gap: 24px;
+ margin: 24px 0 0 0;
+ }
+ .fan-card {
+ background: #fff;
+ border-radius: 14px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.04);
+ flex: 1;
+ padding: 28px 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ min-width: 0;
+ }
+ .fan-card .label {
+ color: #888;
+ font-weight: 600;
+ margin-bottom: 8px;
+ }
+ .fan-card .circle {
+ margin-bottom: 8px;
+ }
+ .fan-card .value {
+ font-size: 1.7rem;
+ font-weight: bold;
+ color: #204080;
+ }
+ .fan-card .unit {
+ font-size: 13px;
+ color: #bbb;
+ margin-top: 2px;
+ }
+ .section {
+ background: #fff;
+ border-radius: 14px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.04);
+ margin-top: 32px;
+ padding: 24px 28px;
+ }
+ .section-title {
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 18px;
+ }
+ .pools-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 15px;
+ }
+ .pools-table th, .pools-table td {
+ padding: 10px 8px;
+ text-align: center;
+ }
+ .pools-table th {
+ background: #f3f7fa;
+ color: #204080;
+ font-weight: 600;
+ }
+ .pools-table tr:not(:last-child) {
+ border-bottom: 1px solid #e0e6ed;
+ }
+ .badge {
+ display: inline-block;
+ padding: 2px 14px;
+ border-radius: 12px;
+ font-size: 13px;
+ font-weight: 600;
+ }
+ .badge-normal {
+ background: #e3f2fd;
+ color: #1976d2;
+ }
+ .badge-error {
+ background: #ffebee;
+ color: #d32f2f;
+ }
+ .diagnostic-log {
+ font-family: 'Fira Mono', 'Consolas', monospace;
+ color: #d32f2f;
+ background: #fff5f5;
+ border-radius: 8px;
+ padding: 12px 16px;
+ font-size: 14px;
+ max-height: 120px;
+ overflow-y: auto;
+ margin-top: 8px;
+ }
+ @media (max-width: 1100px) {
+ .summary-row, .fan-row { flex-direction: column; gap: 12px; }
+ }
+ @media (max-width: 800px) {
+ .container { flex-direction: column; }
+ .sidebar { width: 100%; flex-direction: row; height: 60px; }
+ .sidebar-logo { padding: 10px 12px; font-size: 16px; }
+ .sidebar-menu { display: flex; flex-direction: row; }
+ .sidebar-menu ul { display: flex; }
+ .sidebar-menu li { padding: 8px 16px; font-size: 14px; }
+ .main { padding: 0 4px; }
+ .header { padding: 10px 12px; }
+ .section { padding: 12px 6px; }
+ }
diff --git a/miner/imgs/extinguish.png b/miner/imgs/extinguish.png
new file mode 100644
index 0000000..657b8e3
Binary files /dev/null and b/miner/imgs/extinguish.png differ
diff --git a/miner/imgs/logo.png b/miner/imgs/logo.png
new file mode 100644
index 0000000..ad036e2
Binary files /dev/null and b/miner/imgs/logo.png differ
diff --git a/miner/imgs/poweroff.png b/miner/imgs/poweroff.png
new file mode 100644
index 0000000..ed89ae7
Binary files /dev/null and b/miner/imgs/poweroff.png differ
diff --git a/miner/imgs/reboot.png b/miner/imgs/reboot.png
new file mode 100644
index 0000000..4eb92d3
Binary files /dev/null and b/miner/imgs/reboot.png differ
diff --git a/miner/imgs/red.png b/miner/imgs/red.png
new file mode 100644
index 0000000..6812b16
Binary files /dev/null and b/miner/imgs/red.png differ
diff --git a/miner/imgs/reset.png b/miner/imgs/reset.png
new file mode 100644
index 0000000..39ccbee
Binary files /dev/null and b/miner/imgs/reset.png differ
diff --git a/miner/imgs/restart.svg b/miner/imgs/restart.svg
new file mode 100644
index 0000000..d9e6f36
--- /dev/null
+++ b/miner/imgs/restart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/miner/imgs/save.png b/miner/imgs/save.png
new file mode 100644
index 0000000..2378987
Binary files /dev/null and b/miner/imgs/save.png differ
diff --git a/miner/imgs/switch.svg b/miner/imgs/switch.svg
new file mode 100644
index 0000000..d081736
--- /dev/null
+++ b/miner/imgs/switch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/miner/imgs/色标.png b/miner/imgs/色标.png
new file mode 100644
index 0000000..de689a4
Binary files /dev/null and b/miner/imgs/色标.png differ
diff --git a/miner/index.html b/miner/index.html
new file mode 100644
index 0000000..38446aa
--- /dev/null
+++ b/miner/index.html
@@ -0,0 +1,130 @@
+
+
+
+
+
+ Matches
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Elapsed
+
96427.17
+
GH/S
+
+
+
+
Average
+
95706.09
+
GH/S
+
+
+
+
+
+
Fan1
+
+
+
+
3000
+
Speed (r/min)
+
+
+
Fan2
+
+
+
+
3000
+
Speed (r/min)
+
+
+
+
+
Pools
+
+
+
+
+ Pool |
+ URL |
+ User |
+ Status |
+ Diff |
+ GetWorks |
+ Accepted |
+ Rejected |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/miner/js/index.js b/miner/js/index.js
new file mode 100644
index 0000000..ba19442
--- /dev/null
+++ b/miner/js/index.js
@@ -0,0 +1,89 @@
+/**
+ * 假数据
+ */
+const pools = [
+ {
+ pool: 1,
+ url: "http://34343424224:433",
+ user: "AABBBB",
+ status: "Normal",
+ diff: "524k",
+ getWorks: 652,
+ accepted: 2965,
+ rejected: 0,
+ },
+ {
+ pool: 1,
+ url: "http://34343424224:433",
+ user: "AABBBB",
+ status: "Normal",
+ diff: "666k",
+ getWorks: 1000,
+ accepted: 2000,
+ rejected: 0,
+ },
+ {
+ pool: 1,
+ url: "http://34343424224:433",
+ user: "AABBBB",
+ status: "Error",
+ diff: "-",
+ getWorks: "-",
+ accepted: "-",
+ rejected: 0,
+ },
+ ];
+
+ const logs = [
+ "Apr 24 17:15:58 miner local0.err cgminer: error_event:=init miner board 1 fail!",
+ "Apr 24 17:15:58 miner local0.err cgminer: error_event:=init miner board 1 fail!",
+ "Apr 24 17:15:58 miner local0.err cgminer: error_event:=init miner board 1 fail!",
+ "Apr 24 17:15:58 miner local0.err cgminer: error_event:=init miner board 1 fail!",
+ ];
+
+ /**
+ * 渲染矿池表格
+ */
+ const renderPools = () => {
+ const tbody = document.getElementById('pools-tbody');
+ if (!tbody) return;
+ tbody.innerHTML = pools.map(pool => `
+
+ ${pool.pool} |
+ ${pool.url} |
+ ${pool.user} |
+
+
+ ${pool.status}
+
+ |
+ ${pool.diff} |
+ ${pool.getWorks} |
+ ${pool.accepted} |
+ ${pool.rejected} |
+
+ `).join('');
+ };
+
+ /**
+ * 渲染诊断日志
+ */
+ const renderLogs = () => {
+ const logDiv = document.getElementById('diagnostic-log');
+ if (!logDiv) return;
+ logDiv.innerHTML = logs.map(log => `${log}
`).join('');
+ };
+
+ /**
+ * 重启按钮事件
+ */
+ const handleRestart = () => {
+ alert('重启功能未实现');
+ };
+
+ // 初始化
+ window.addEventListener('DOMContentLoaded', () => {
+ renderPools();
+ renderLogs();
+ window.handleRestart = handleRestart;
+ });
\ No newline at end of file