From f033e71095229cad4791a5095003d13b06dafd0c Mon Sep 17 00:00:00 2001 From: ypsdf1 Date: Wed, 30 Sep 2026 12:11:49 +0800 Subject: [PATCH] =?UTF-8?q?SN=E7=AE=A1=E7=90=86=E7=AB=AF=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20issue=20=E5=8A=9E=E7=90=86=E7=AD=BE=E5=8F=91=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=EF=BC=9A=E4=B8=A4=E6=9D=A1=E4=BB=B6=E7=A1=AC=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E5=B9=B6=E5=88=86=E5=88=AB=E6=8F=90=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?isForce=20=E5=9B=BA=E5=AE=9A=E4=B8=BA=200=EF=BC=9B=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=AB=AF=E8=AF=A6=E6=83=85=E9=A1=B5=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E5=8A=9E=E7=90=86=E7=AD=BE=E5=8F=91=E6=8C=89=E9=92=AE=E4=B8=8E?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin.php | 6 ++++-- api/sn.php | 21 +++++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/admin.php b/admin.php index fd785a1..f1c4e94 100644 --- a/admin.php +++ b/admin.php @@ -4209,6 +4209,7 @@ async function renderSnDetail(el, sn) { '' + '' + '' + + '' + '' + '

命令通过 web_sn_commands 下发,游戏服 10~30 秒内执行并回执。' + '
强制注销:豁免三条件门槛,直接执行且不进入冷静期;强制补发:豁免三条件门槛,按定义直接执行;' + @@ -4288,7 +4289,7 @@ async function snAdmCmd(cmd, force) { if (force === undefined || force === null) force = 1; const sn = snAdm.sn; if (!sn) return; - const names = { locate: '定位', reissue: '强制补发', cancel: (force ? '强制注销' : '代办注销'), bind: '永久绑定', report_check: '报失核查' }; + const names = { locate: '定位', reissue: '强制补发', cancel: (force ? '强制注销' : '代办注销'), bind: '永久绑定', report_check: '报失核查', issue: '办理签发' }; const warns = { locate: '立即查询该SN在游戏世界中的位置?', reissue: '强制补发 ' + sn + '?旧SN作废并签发新SN,玩家需在线。', @@ -4296,7 +4297,8 @@ async function snAdmCmd(cmd, force) { ? '强制注销 ' + sn + '?豁免三条件门槛,将销毁对应实物并直接注销,不进入1小时冷静期。' : '代办注销 ' + sn + '?按三条件门槛校验(不在本人身上 / 不在本人领地箱子 / 脱离自身管控超12小时),未达标会被拒绝;成功后进入1小时冷静期。', bind: '把 ' + sn + ' 永久绑定为非法物品?该SN不可恢复。', - report_check: '立即核查 ' + sn + ' 的当前位置并给出报失结论?' + report_check: '立即核查 ' + sn + ' 的当前位置并给出报失结论?', + issue: '为 ' + sn + ' 办理签发新设备?前提:旧SN已注销解绑 且 注销冷静期已结束(1小时),未达标会分别提示是哪一条未通过。' }; if (!await glassConfirm(warns[cmd] || ('确认对 ' + sn + ' 执行「' + names[cmd] + '」?'))) return; try { diff --git a/api/sn.php b/api/sn.php index 0f279a2..5dc77d2 100644 --- a/api/sn.php +++ b/api/sn.php @@ -1201,7 +1201,7 @@ function snAdminCmd() { $cmd = trim(getParam('cmd', '')); $sn = trim(getParam('sn', '')); $reason = trim(getParam('reason', '')); - $allowed = ['cancel', 'reissue', 'locate', 'bind', 'report_check']; + $allowed = ['cancel', 'reissue', 'locate', 'bind', 'report_check', 'issue']; if (!in_array($cmd, $allowed, true)) error('非法命令'); if ($sn === '') error('缺少sn'); @@ -1212,12 +1212,29 @@ function snAdminCmd() { $row = $rr->fetchArray(SQLITE3_ASSOC); if (!$row) error('SN不存在'); + // issue(办理签发):两条硬校验、分别提示哪条不达标(与玩家端最小化提示相反)。 + // error() 直接 exit → 两条提示天然互斥。校验通过才入队,isForce 固定为 0(无豁免)。 + if ($cmd === 'issue') { + $st = (string)$row['status']; + if (!in_array($st, array('cancelled', 'destroyed', 'reissued'), true)) { + error('旧SN尚未注销解绑,当前状态:' . snStatusCn($st) + . '。请先完成注销/销毁/补发后再办理'); + } + $cdUntil = snCooldownLeft($db, (string)$row['owner']); + $nowTs = snNow(); + if ($cdUntil > $nowTs) { + error('注销冷静期未结束,还剩 ' . ceil(($cdUntil - $nowTs) / 60) . ' 分钟'); + } + } + // ★ is_force=1(默认,强制操作):Java 侧本次绕过冷静期 + 绕过三条件门槛 // (强制注销 / 强制补发按定义豁免"脱离自身管控"三项)。 // 代办操作传 force=0 → 照常按三条件校验,逐条判定见 SN 详情的 custody。 $force = (int)getParam('force', 1) ? 1 : 0; + // issue 不受 $force 影响(校验是硬的、无豁免);cancel/reissue 等原有 force 语义不变。 $id = snEnqueueCmd($db, $cmd, $sn, $row['owner'], $row['item_type'], - $reason !== '' ? $reason : '管理员操作', '', 0, $force); + $reason !== '' ? $reason : ($cmd === 'issue' ? '管理员办理签发' : '管理员操作'), + '', 0, $cmd === 'issue' ? 0 : $force); success(['id' => $id], '命令已下发,等待游戏服务器执行(10~30 秒)'); }