diff --git a/cmd/client/main.go b/cmd/client/main.go index 7bb8670..dda758f 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -1095,12 +1095,16 @@ func tryNvidiaSMI() []GPUInfo { var gpus []GPUInfo for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") { parts := strings.Split(line, ",") - if len(parts) < 10 { + if len(parts) < 11 { continue } for i := range parts { parts[i] = strings.TrimSpace(parts[i]) } + fan := parseFloat(parts[10]) + if parts[10] == "[N/A]" || parts[10] == "N/A" || strings.Contains(parts[10], "[") { + fan = 0 + } gpus = append(gpus, GPUInfo{ Name: parts[1], VRAMTotalMB: parseFloat(parts[2]), @@ -1110,7 +1114,7 @@ func tryNvidiaSMI() []GPUInfo { CoreClock: parseFloat(parts[7]), MemClock: parseFloat(parts[8]), Power: parseFloat(parts[9]), - FanSpeed: parseFloat(parts[10]), + FanSpeed: fan, }) } return gpus diff --git a/cmd/server/templates/index.html b/cmd/server/templates/index.html index 7038d4f..af38b47 100644 --- a/cmd/server/templates/index.html +++ b/cmd/server/templates/index.html @@ -507,7 +507,8 @@ display: flex; flex-direction: column; gap: 3px; - padding: 0 12px 8px + padding: 0 12px 8px; + align-self: stretch } .card-left { @@ -678,59 +679,100 @@ } /* ═══ GPU ═══ */ - .gpu-table-wrap { - overflow-x: auto + .gpu-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); + gap: 5px } - .gpu-table { - width: 100%; - border-collapse: collapse; + .gpu-block { + background: rgba(0, 0, 0, .2); + border-radius: 6px; + padding: 6px; + cursor: pointer; + transition: background .2s, transform .15s + } + + .gpu-block:hover { + background: rgba(0, 229, 160, .06); + transform: translateY(-1px) + } + + .gb-top { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 4px + } + + .gb-name { font-size: 8px; + color: var(--dim); font-family: var(--mono) } - .gpu-table th { - text-align: left; - font-size: 7px; - font-weight: 600; - letter-spacing: .4px; - text-transform: uppercase; - color: var(--dim); - padding: 2px 4px; - border-bottom: 1px solid var(--border); - white-space: nowrap + .gb-temp { + font-size: 11px; + font-weight: 700; + font-family: var(--mono) } - .gpu-table td { - padding: 2px 4px; - border-bottom: 1px solid rgba(30, 37, 58, .5); - white-space: nowrap + .gb-bar { + position: relative; + height: 14px; + background: var(--dim-bar); + border-radius: 3px; + overflow: hidden; + margin-bottom: 3px } - .gpu-table tr:last-child td { - border-bottom: none + .gb-fill { + height: 100%; + border-radius: 3px; + transition: width .5s ease } - .gpu-table tr:hover td { - background: rgba(0, 229, 160, .03) - } - - .gpu-idx { - color: var(--dim); - font-size: 10px - } - - .gpu-nm { - font-family: var(--font); - font-weight: 500; - font-size: 11px - } - - .gpu-vram-cell { + .gb-pct { + position: absolute; + inset: 0; display: flex; - flex-direction: column; - gap: 2px; - min-width: 60px + align-items: center; + justify-content: center; + font-size: 8px; + font-weight: 700; + font-family: var(--mono); + color: #fff; + text-shadow: 0 1px 2px rgba(0,0,0,.6) + } + + .gb-info { + display: flex; + justify-content: space-between; + font-size: 7px; + font-family: var(--mono) + } + + .gpu-detail-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 4px 10px + } + + .gd-item { + display: flex; + justify-content: space-between; + align-items: center + } + + .gd-l { + color: var(--dim); + font-size: 9px + } + + .gd-v { + font-family: var(--mono); + font-size: 9px; + font-weight: 500 } /* ═══ Mining ═══ */ @@ -1416,37 +1458,61 @@ function buildGPU(gpus, infoGPUs, isOn) { var list = isOn ? gpus : (infoGPUs || []); - if (!list.length) return '
| \u7F16\u53F7 | \u8D1F\u8F7D | \u6E29\u5EA6 | \u529F\u8017 | \u6838\u5FC3 | \u663E\u5B58 | \u7528\u91CF | \u98CE\u6247 | ' - + '|
|---|---|---|---|---|---|---|---|---|
| GPU' + (i + 1) + ' | ' - + '' + gl.toFixed(0) + '% | ' - + '' + tT(tmp > 0 ? tmp : null) + ' | ' - + '' + Math.round(pwr) + ' W | ' - + '' + Math.round(cc) + ' MHz | ' - + '' + Math.round(mc) + ' MHz | '; - if (vt > 0) { - var vp = vu / vt * 100; - h += '' + (vu / 1024).toFixed(1) + '/' + (vt / 1024).toFixed(0) + 'G'
- + ' | ';
- } else {
- h += '\u2014 | '; - } - h += '' + (fan > 0 ? Math.round(fan) + '%' : '\u2014') + ' | '; - h += '