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 秒)');
}