diff --git a/Scoreboard.png b/Scoreboard.png new file mode 100644 index 0000000..1db38d4 Binary files /dev/null and b/Scoreboard.png differ diff --git a/console/main/tray-icon.js b/console/main/tray-icon.js index 15319e7..5e846be 100644 --- a/console/main/tray-icon.js +++ b/console/main/tray-icon.js @@ -1,16 +1,35 @@ 'use strict' -const { nativeImage } = require('electron') +const fs = require('fs') +const path = require('path') +const { app, nativeImage } = require('electron') -// 托盘图标以 base64 内嵌:现场部署包只有 exe 和几个文件, -// 少一个需要跟着走的资源文件就少一处「文件丢了图标不显示」的故障点。 +// 托盘图标:优先用部署包里的 scoreboard.png(换图标不用重新打包), +// 找不到时回落到内嵌 base64,保证任何情况下托盘都有图标。 const ICON_PNG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABUklEQVR42u2XwUdEURTG5z9JSholJY2SklJSf0+0iKFFtIhoES0iWkSLiBaRDKNSKU2GjCRGEkkSSZsvb3GfnHPnzTm382Y1P36b9x33fKv37stkmiiYLf1AovnimatvhPjvxdMXX7AwaPnU6ScsVS2fLH4gDUXLJwrvSNO6BcaP3pCmicvHDl/RCGsWGD14QSP0Lh/Zf4aVFN8MKzC89wQrKb4ZVmBotworKb4ZVmBw5xFWUnwzrEBu+wFWUnwzrMDA1j00UqSZkxXo36xAI0WaOVmBvo07aKRIMycr0LtehkaKNHOyAj1rt9BIkWZO79uwe/UGUinSLLLmt6Br5Rp/pVhkkYlfxOzyJZwUi6zufaBz6RxOikUmuhV1LJ4hkuKeh2aqe2F7/oQdFD1zarOgmzE9qG2hGKvJgv8L6EGt84VYTWZWoGXuOFaTNX9qk/gFLmHiXP3t+GEAAAAASUVORK5CYII=' +// 候选顺序:exe 同级(部署包)→ 源码目录(开发态)→ resources 目录 +function resolveIconPath() { + const candidates = [ + path.join(path.dirname(app.getPath('exe')), 'scoreboard.png'), + path.join(__dirname, '..', 'scoreboard.png'), + path.join(process.resourcesPath || '', 'scoreboard.png'), + ] + return candidates.find((candidate) => candidate && fs.existsSync(candidate)) || null +} + function createTrayIcon() { - const image = nativeImage.createFromDataURL(`data:image/png;base64,${ICON_PNG_BASE64}`) - // Windows 上托盘按 16px 显示,缩放交给系统会更模糊,这里直接给 16px - return image.resize({ width: 16, height: 16 }) + const file = resolveIconPath() + if (file) { + const image = nativeImage.createFromPath(file) + if (!image.isEmpty()) { + // Windows 托盘按 16px 显示,缩放交给系统会更模糊,这里直接给 16px + return image.resize({ width: 16, height: 16 }) + } + } + const fallback = nativeImage.createFromDataURL(`data:image/png;base64,${ICON_PNG_BASE64}`) + return fallback.resize({ width: 16, height: 16 }) } module.exports = { createTrayIcon } diff --git a/console/renderer/index.html b/console/renderer/index.html index 23add5d..64aa60f 100644 --- a/console/renderer/index.html +++ b/console/renderer/index.html @@ -13,7 +13,7 @@
- +

Scoreboard Console

赛事积分榜 · 桌面宿主

diff --git a/console/renderer/scoreboard.png b/console/renderer/scoreboard.png new file mode 100644 index 0000000..bfe9607 Binary files /dev/null and b/console/renderer/scoreboard.png differ diff --git a/console/renderer/styles.css b/console/renderer/styles.css index 724c691..8fe474a 100644 --- a/console/renderer/styles.css +++ b/console/renderer/styles.css @@ -51,10 +51,11 @@ body { } .brand-mark { - width: 8px; - height: 22px; - border-radius: 4px; - background: linear-gradient(180deg, var(--accent), #1b6bb8); + width: 30px; + height: 30px; + border-radius: 8px; + object-fit: cover; + flex: none; } h1 { diff --git a/console/scoreboard.png b/console/scoreboard.png new file mode 100644 index 0000000..3ca9c6b Binary files /dev/null and b/console/scoreboard.png differ diff --git a/deploy/build.bat b/deploy/build.bat index f537586..2261e9c 100644 --- a/deploy/build.bat +++ b/deploy/build.bat @@ -53,6 +53,8 @@ REM config.json must sit next to the exe: the console resolves it from the exe d copy /y "console\config.json" "%CONSOLE_OUT%\config.json" >nul || exit /b 1 copy /y "dist\scoreboard.exe" "%CONSOLE_OUT%\scoreboard.exe" >nul || exit /b 1 copy /y "config.yaml" "%CONSOLE_OUT%\config.yaml" >nul || exit /b 1 +REM app icon: the console loads it from the exe directory for tray / window icon +copy /y "console\scoreboard.png" "%CONSOLE_OUT%\scoreboard.png" >nul || exit /b 1 echo. echo === 构建完成 === diff --git a/server/internal/httpapi/export_handlers.go b/server/internal/httpapi/export_handlers.go index 1e8ab7a..ff122c6 100644 --- a/server/internal/httpapi/export_handlers.go +++ b/server/internal/httpapi/export_handlers.go @@ -90,8 +90,16 @@ func (s *server) exportProjectZip(w http.ResponseWriter, r *http.Request) (any, if err := os.MkdirAll(dir, 0o755); err != nil { return nil, internal(err) } + // 项目名取赛事设置里的 event.name;为空会触发 SafeProjectName 校验失败,回退到固定名 + name := "scoreboard-project" + var raw string + if err := s.ev.QueryRowContext(r.Context(), + `SELECT value FROM settings WHERE key = 'event.name'`).Scan(&raw); err == nil && raw != "" { + name = raw + } + dst := filepath.Join(dir, "project-"+time.Now().Format("20060102-150405")+".zip") - if _, err := export.ExportProjectZip(s.ev, dst, export.ProjectExportOptions{}); err != nil { + if _, err := export.ExportProjectZip(s.ev, dst, export.ProjectExportOptions{Name: name}); err != nil { return nil, internal(err) } defer func() { _ = os.Remove(dst) }() diff --git a/web/admin.html b/web/admin.html index d8c8118..81c5a33 100644 --- a/web/admin.html +++ b/web/admin.html @@ -3,6 +3,7 @@ + 管理面板 diff --git a/web/display.html b/web/display.html index 0330350..ad12f2c 100644 --- a/web/display.html +++ b/web/display.html @@ -3,6 +3,7 @@ + 积分大屏 diff --git a/web/index.html b/web/index.html index c21f3b0..6727d57 100644 --- a/web/index.html +++ b/web/index.html @@ -3,6 +3,7 @@ + 赛事积分榜系统 diff --git a/web/public/favicon.png b/web/public/favicon.png new file mode 100644 index 0000000..295bd83 Binary files /dev/null and b/web/public/favicon.png differ diff --git a/web/public/scoreboard.png b/web/public/scoreboard.png new file mode 100644 index 0000000..bfe9607 Binary files /dev/null and b/web/public/scoreboard.png differ diff --git a/web/src/admin/components/DesktopTitleBar.vue b/web/src/admin/components/DesktopTitleBar.vue index 9c8cff7..41ceee3 100644 --- a/web/src/admin/components/DesktopTitleBar.vue +++ b/web/src/admin/components/DesktopTitleBar.vue @@ -37,7 +37,7 @@ function handleDoubleClick(event: MouseEvent): void {