From d31a34e9aa207a493cfb3a6d7439fbd463b6a407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=B5=E5=AE=9D=E4=BB=99=E5=B0=8A?= Date: Wed, 4 Nov 2026 15:09:15 +0800 Subject: [PATCH] =?UTF-8?q?GM=20=E5=B7=A5=E5=85=B7=EF=BC=9A=E7=82=B9?= =?UTF-8?q?=E5=88=B8=E5=AE=9E=E6=97=B6=E5=88=B7=E6=96=B0=20+=20=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E6=8E=92=E7=89=88=E4=B8=8E=E6=96=87=E6=A1=88=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 服务端: - gm_tool_wallet.go: GMAdjustAccountCera 落库后遍历在线会话,推送账号级 点券钱包投影(op53),在线角色点券余额即时刷新,无需离线/重登 启动器前端: - app.js: 副本控制改名「魔改中心」;删除角色详情页疲劳值编辑块 (saveFatigue/maxFatigue 及相关输入框);黑钻提示改为「在线回城即时生效」 - index.html/shell.css/shell.js/style.css: 精简 GM 全屏标题栏(仅保留 窗口按钮)、移除 D 字图标及死样式、修正侧边栏底部间距 --- launcher/app.js | 41 ++----------------- launcher/index.html | 6 +-- launcher/shell.css | 18 ++++---- launcher/shell.js | 5 --- launcher/style.css | 11 +---- .../services/dnfbridge/gm_tool_wallet.go | 15 +++++++ 6 files changed, 29 insertions(+), 67 deletions(-) diff --git a/launcher/app.js b/launcher/app.js index 1e7a818..d36fd12 100644 --- a/launcher/app.js +++ b/launcher/app.js @@ -276,7 +276,7 @@ const GM_PAGES = { inventory: ['背包装备', '/ 查看背包'], auction: ['拍卖行', '/ 挂单上下架'], quests: ['任务管理', '/ 任务查询'], - dungeons: ['副本控制', '/ 副本状态'], + dungeons: ['魔改中心', '/ 副本状态'], wallet: ['钱包点券', '/ 钱包与黑钻'], wipe: ['删档管理', '/ 删除角色与账号'], settings: ['连接设置', '/ 数据源切换'], @@ -620,8 +620,6 @@ async function openCharDetail(charId) { try { const r = await api('/api/character?id=' + encodeURIComponent(charId)); const ch = r.data || {}; - const fat = await api('/api/character/fatigue?id=' + encodeURIComponent(charId) + '&mode=query'); - const fatInfo = fat.data || {}; content.innerHTML = `
角色:${escapeHtml(ch.name || charId)}
@@ -651,23 +649,6 @@ async function openCharDetail(charId) {
职业 / 转职
正在加载职业信息…
- -
疲劳值(无限疲劳)
-
-
- - -
-
- - -
-
-
- - - 疲劳每日 6 点重置回上限;无限疲劳 = 把疲劳和上限都设成超大值 -
@@ -779,20 +760,6 @@ async function saveGold() { if (r.ok) gmToast('金币已更新', 'ok'); else gmToast('失败:' + (r.error || ''), 'err'); } -async function saveFatigue() { - const fatigue = $('editFatigue').value; - const limit = $('editFatigueLimit').value; - const r = await post('/api/character/fatigue', { id: currentCharId, fatigue: parseInt(fatigue), fatigue_limit: parseInt(limit) }); - if (r.ok) { gmToast('疲劳值已更新', 'ok'); openCharDetail(currentCharId); } - else gmToast('失败:' + (r.error || ''), 'err'); -} - -async function maxFatigue() { - const r = await post('/api/character/fatigue', { id: currentCharId, fatigue: 999999, fatigue_limit: 999999 }); - if (r.ok) { gmToast('已设置无限疲劳(999999)', 'ok'); openCharDetail(currentCharId); } - else gmToast('失败:' + (r.error || ''), 'err'); -} - async function deleteCurrentChar() { gmConfirm('删除角色', '确定要删除该角色的全部数据吗?
此操作不可恢复,且需先停止服务端。', 'DELETE', async () => { const r = await post('/api/character/delete', { id: currentCharId, confirm: 'DELETE' }); @@ -1988,7 +1955,7 @@ async function renderWallet(content) {
-
黑钻提升疲劳上限、额外翻牌等权益;角色需离线(下次登录生效)。
+
黑钻提升疲劳上限、额外翻牌等权益;在线角色回城后即时生效,无需离线。
`; fillCharSelect($('wallet-char')); fillAccountSelect($('cera-account')); @@ -2066,7 +2033,7 @@ async function activateBlackDiamond() { const id = $('bd-char').value; const days = parseInt($('bd-days').value) || 30; if (!id) { gmToast('请选择角色', 'err'); return; } - gmConfirm('开启黑钻', '确定要为所选角色开启黑钻 ' + days + ' 天吗?
角色需处于离线状态,下次登录生效。', '开启黑钻', async () => { + gmConfirm('开启黑钻', '确定要为所选角色开启黑钻 ' + days + ' 天吗?
在线角色回城后即时生效。', '开启黑钻', async () => { const r = await post('/api/black-diamond/activate', { id, days }); if (r.ok) { gmToast('黑钻已开启 ' + days + ' 天', 'ok'); queryBlackDiamond(); } else gmToast('开启失败:' + (r.error || ''), 'err'); @@ -2290,8 +2257,6 @@ function init() { window.openCharDetail = openCharDetail; window.saveLevel = saveLevel; window.saveGold = saveGold; -window.saveFatigue = saveFatigue; -window.maxFatigue = maxFatigue; window.deleteCurrentChar = deleteCurrentChar; window.doGrant = doGrant; window.loadInventory = loadInventory; diff --git a/launcher/index.html b/launcher/index.html index 0356210..3fe564f 100644 --- a/launcher/index.html +++ b/launcher/index.html @@ -208,7 +208,7 @@
-

控制台

/ 服务端总览
+

控制台

/ 服务端总览
diff --git a/launcher/shell.css b/launcher/shell.css index 79820b4..b0d0d95 100644 --- a/launcher/shell.css +++ b/launcher/shell.css @@ -181,7 +181,7 @@ button,input,select{font:inherit} /* GM embedded */ #page-gm{padding:0} #page-gm.active{height:100%} -#page-gm #gmView{height:100%;display:flex;background:#0b0b14;border:0} +#page-gm #gmView{height:100%;margin-top:0;display:flex;background:#0b0b14;border:0} #page-gm .gm-sidebar{width:180px} #page-gm .gm-main{flex:1;min-width:0} #page-gm .gm-content{height:calc(100% - 58px);overflow:auto} @@ -409,22 +409,18 @@ body{font-size:16px} /* ================= GM 全屏模式(点击 GM 标签覆盖整个窗口) ================= */ body.gm-fullscreen #appShell{height:100vh} -body.gm-fullscreen .shell-topnav{display:none} +/* 全屏时保留主标题栏作为极简标题栏:隐藏品牌与导航,仅右上角窗口控制按钮贴顶 */ +body.gm-fullscreen .shell-topnav{height:34px;background:transparent;border-bottom:0;padding:0 4px 0 0} +body.gm-fullscreen .shell-brand{display:none} +body.gm-fullscreen .shell-nav{display:none} +body.gm-fullscreen .shell-win-controls{height:100%} body.gm-fullscreen .shell-topbar{display:none} body.gm-fullscreen .shell-statusbar{display:none} -body.gm-fullscreen #page-gm #gmView{height:100%} +body.gm-fullscreen #page-gm #gmView{height:100%;margin-top:0} body.gm-fullscreen .shell-main{overflow:hidden} /* GM 全屏下隐藏窗口缩放热区(铺满工作区时不可再拖边) */ body.gm-fullscreen .win-resize{display:none} -/* GM 顶部栏内的窗口按钮:仅在全屏模式(顶部导航隐藏)时显示 */ -.gm-win-btn{display:none;width:28px;height:24px;border:1px solid var(--border,#25483a); - background:transparent;color:#a8c7b6;cursor:pointer;font-size:14px;line-height:1; - border-radius:3px;flex-shrink:0} -.gm-win-btn:hover{background:#1a3a2c;color:#fff} -.gm-win-close:hover{background:#7a2a33;border-color:#a33a44;color:#fff} -body.gm-fullscreen .gm-win-btn{display:inline-block} - /* ================= 标题栏右侧窗口控制按钮(最小化/关闭,无边框线性图标) ================= */ .shell-topnav{cursor:move;user-select:none;padding:0 6px 0 16px} .shell-topnav button,.shell-topnav .shell-side-foot{cursor:default} diff --git a/launcher/shell.js b/launcher/shell.js index 417ae6a..238b758 100644 --- a/launcher/shell.js +++ b/launcher/shell.js @@ -66,11 +66,6 @@ const bMin = $('shellWinMin'); if (bMin) bMin.addEventListener('click', () => { const w = win(); if (w && w.minimize) w.minimize(); }); const bClose = $('shellWinClose'); if (bClose) bClose.addEventListener('click', () => { const w = win(); if (w && w.close) w.close(); }); - // GM 全屏模式下的窗口按钮(最小化 / 关闭) - const gmWinMin = $('gmWinMin'); - const gmWinClose = $('gmWinClose'); - if (gmWinMin) gmWinMin.addEventListener('click', () => { const w = win(); if (w && w.minimize) w.minimize(); }); - if (gmWinClose) gmWinClose.addEventListener('click', () => { const w = win(); if (w && w.close) w.close(); }); // 账号登录:打开原账号管理弹窗,可选择默认账号 $('shellAccount').addEventListener('click', () => { diff --git a/launcher/style.css b/launcher/style.css index 312e9b2..a5cdf84 100644 --- a/launcher/style.css +++ b/launcher/style.css @@ -471,17 +471,8 @@ html, body { .gm-logo { display: flex; align-items: center; - gap: 10px; padding: 4px 10px 20px; } -.gm-logo-mark { - width: 38px; height: 38px; - border-radius: 11px; - background: linear-gradient(135deg, var(--primary), var(--primary-2)); - display: flex; align-items: center; justify-content: center; - font-weight: 800; font-size: 18px; color: #fff; - box-shadow: 0 0 22px rgba(124, 92, 255, 0.35); -} .gm-logo-title { font-size: 17px; font-weight: 700; letter-spacing: 0.5px; } .gm-logo-sub { font-size: 11px; color: var(--text-muted); margin-top: 2px; } @@ -518,7 +509,7 @@ html, body { .gm-sidebar-foot { margin-top: auto; - padding: 12px; + padding: 12px 12px 20px; font-size: 11px; color: var(--text-muted); display: flex; diff --git a/server/internal/services/dnfbridge/gm_tool_wallet.go b/server/internal/services/dnfbridge/gm_tool_wallet.go index 0aba8a3..9d969ea 100644 --- a/server/internal/services/dnfbridge/gm_tool_wallet.go +++ b/server/internal/services/dnfbridge/gm_tool_wallet.go @@ -247,5 +247,20 @@ func (s *Service) GMAdjustAccountCera(ctx context.Context, request GMAccountCera } after, _ := currency.BalanceOf(account) result.After = after + + // 落库后推送给该账号下所有在线角色:点券是账号级钱包,需刷新每个已选角色的 + // 钱包投影(class-0 op53),让在线角色的点券余额即时刷新,不必离线/重登。 + for _, session := range s.currentOnlineChatSessions() { + if session == nil { + continue + } + if strings.TrimSpace(s.accountIDForSession(session)) != accountID { + continue + } + if _, pushErr := s.sendCurrentGoldConsignWalletRefresh(session); pushErr != nil { + s.logWarn("dnf90 GM cera live refresh failed", + "account_id", accountID, "currency", currencyName, "error", pushErr) + } + } return result, nil }