From 3dacc80fe1f76ce3e2bb95c5742f0b251f1b5192 Mon Sep 17 00:00:00 2001 From: ypsdf1 Date: Mon, 29 Jun 2026 20:45:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A2=86=E5=9C=B0=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=B5=B0pending=E9=98=9F=E5=88=97=20+=20sync=E6=B8=85=E7=90=86?= =?UTF-8?q?PHP=E6=AE=8B=E7=95=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - land_api: handleDeleteLand改为写web_admin_changes队列 - land_api: 新增delete_land_callback处理Java回调 - sync.php: syncLands增加删除PHP中不存在的领地 - 修复admin面板过户按钮(同步到plugin目录) --- api/land_api.php | 64 +++++++++++++++++++++++++++++++++++++++++++++--- api/sync.php | 28 ++++++++++++++++++++- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/api/land_api.php b/api/land_api.php index 79fb5ba..1d1b9a1 100644 --- a/api/land_api.php +++ b/api/land_api.php @@ -102,7 +102,7 @@ try { // ★ 成员独立权限操作action(领地所有者编辑成员权限) $memberPermActions = ['get_member_perms', 'update_member_perm', 'clear_member_perm']; // ★ Java端轮询PHP管理员变更 + Java回调过户结果 - $syncFromPhpActions = ['poll_admin_changes', 'ack_admin_changes', 'transfer_callback', 'owner_change_callback']; + $syncFromPhpActions = ['poll_admin_changes', 'ack_admin_changes', 'transfer_callback', 'owner_change_callback', 'delete_land_callback']; if (in_array($action, $syncActions) || in_array($action, $syncFromPhpActions)) { // 同步类:必须有secret @@ -361,6 +361,10 @@ try { handleOwnerChangeCallback($db, $_POST + $_GET); break; + case 'delete_land_callback': + handleDeleteLandCallback($db, $_GET); + break; + // ===== 用户组管理 ===== case 'list_user_groups': handleListUserGroups($db); @@ -785,11 +789,36 @@ function handleDeleteLand($db, $post) { return; } - $stmt = $db->prepare("DELETE FROM web_area_lands WHERE name = :name"); + // ★ 查询领地信息 + $stmt = $db->prepare("SELECT id, owner FROM web_area_lands WHERE name = :name"); $stmt->bindValue(':name', $name, SQLITE3_TEXT); - $stmt->execute(); + $result = $stmt->execute(); + $row = $result->fetchArray(SQLITE3_ASSOC); + if (!$row) { + echo json_encode(['success' => false, 'error' => '领地不存在']); + return; + } + $landId = (int)$row['id']; - echo json_encode(['success' => true]); + // ★ 检查是否已有pending的land_delete(防止重复提交) + $stmtCheck = $db->prepare("SELECT id FROM web_admin_changes WHERE change_type = 'land_delete' AND target_name = :name AND status = 'pending'"); + $stmtCheck->bindValue(':name', $name, SQLITE3_TEXT); + $checkResult = $stmtCheck->execute(); + if ($checkResult->fetchArray(SQLITE3_ASSOC)) { + echo json_encode(['success' => false, 'error' => '该领地已有待验证的删除请求,请等待Java端处理']); + return; + } + + // ★ 不再直接删除PHP本地副本!写入web_admin_changes让Java端验证后执行 + $stmt4 = $db->prepare("INSERT INTO web_admin_changes (change_type, target_id, target_name, change_data, created_at, status) VALUES ('land_delete', :id, :name, :data, :now, 'pending')"); + $stmt4->bindValue(':id', $landId, SQLITE3_INTEGER); + $stmt4->bindValue(':name', $name, SQLITE3_TEXT); + $stmt4->bindValue(':data', json_encode(['source' => 'admin_panel']), SQLITE3_TEXT); + $stmt4->bindValue(':now', time(), SQLITE3_INTEGER); + $stmt4->execute(); + + debugLog("handleDeleteLand: 管理面板删除领地 {$name} (已写入pending队列,等待Java验证)"); + echo json_encode(['success' => true, 'pending' => true, 'message' => "删除请求已提交: [{$name}],等待Java端验证后生效"]); } function handleUpdateLandOwner($db, $post) { @@ -2269,6 +2298,33 @@ function handleOwnerChangeCallback($db, $post) { } } +/** + * Java端删除领地回调:删除PHP本地副本 + 标记admin_change完成 + */ +function handleDeleteLandCallback($db, $get) { + $name = $get['name'] ?? ''; + $success = ($get['success'] ?? '') === 'true'; + + if (empty($name)) { + echo json_encode(['success' => false, 'error' => '缺少name参数']); + return; + } + + // 删除PHP本地副本 + $stmt = $db->prepare("DELETE FROM web_area_lands WHERE name = :name"); + $stmt->bindValue(':name', $name, SQLITE3_TEXT); + $stmt->execute(); + + // 标记对应的admin_change为completed + $stmtUpd = $db->prepare("UPDATE web_admin_changes SET status = 'completed', acknowledged = 1, acked_at = :now WHERE change_type = 'land_delete' AND target_name = :name AND status = 'pending'"); + $stmtUpd->bindValue(':now', time(), SQLITE3_INTEGER); + $stmtUpd->bindValue(':name', $name, SQLITE3_TEXT); + $stmtUpd->execute(); + + debugLog("handleDeleteLandCallback: 删除领地 {$name} Java端处理成功,已删除PHP副本"); + echo json_encode(['success' => true, 'message' => "领地 [{$name}] 已删除"]); +} + /** * 查询过户状态 */ diff --git a/api/sync.php b/api/sync.php index 3a9442e..3a9c806 100644 --- a/api/sync.php +++ b/api/sync.php @@ -601,7 +601,33 @@ function syncLands() { $stmt->execute(); $count++; } - success("领地同步成功: {$count}个"); + + // ★ 删除PHP中存在但Java同步列表中不存在的领地(解决Java删除后PHP残留问题) + $incomingNames = []; + foreach ($lands as $l) { + $n = $l['name'] ?? ''; + if (!empty($n)) $incomingNames[] = $n; + } + $deletedCount = 0; + if (!empty($incomingNames)) { + $placeholders = implode(',', array_fill(0, count($incomingNames), '?')); + $delStmt = $db->prepare("DELETE FROM web_area_lands WHERE name NOT IN ($placeholders)"); + foreach ($incomingNames as $i => $n) { + $delStmt->bindValue($i + 1, $n, SQLITE3_TEXT); + } + $delStmt->execute(); + $deletedCount = $db->changes(); + } else { + // Java同步列表为空,全删 + $db->exec("DELETE FROM web_area_lands"); + $deletedCount = $db->changes(); + } + + $msg = "领地同步成功: {$count}个"; + if ($deletedCount > 0) { + $msg .= ", 清理PHP残留: {$deletedCount}个"; + } + success($msg); } // ===== 领地权限商店同步 =====