From e49fcaccd841f192f112291fb9e2a88cd860b14c Mon Sep 17 00:00:00 2001 From: ypsdf1 Date: Fri, 10 Jul 2026 10:59:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20syncPermissions=20ON=20CO?= =?UTF-8?q?NFLICT=E6=9B=BF=E4=BB=A3INSERT=20OR=20REPLACE=E9=98=B2=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E9=99=8D=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sync.php + land_api.php: 同步权限时用ON CONFLICT, 保留已有admin/member角色 --- api/land_api.php | 16 ++++++++++++++-- api/sync.php | 17 +++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/api/land_api.php b/api/land_api.php index cff5d68..2a5dabb 100644 --- a/api/land_api.php +++ b/api/land_api.php @@ -994,9 +994,21 @@ function handleSyncPermissions($db, $post) { } $now = time(); - $stmt = $db->prepare("INSERT OR REPLACE INTO web_area_permissions + // ★ 用 ON CONFLICT 替代 INSERT OR REPLACE,避免角色降级 + $stmt = $db->prepare("INSERT INTO web_area_permissions (land_id, land_name, player_name, role, permissions, granted_at, expires_at, synced_at) - VALUES (:land_id, :land_name, :player, :role, :perms, :granted, :expires, :synced)"); + VALUES (:land_id, :land_name, :player, :role, :perms, :granted, :expires, :synced) + ON CONFLICT(land_id, player_name) DO UPDATE SET + land_name = excluded.land_name, + permissions = excluded.permissions, + granted_at = excluded.granted_at, + expires_at = excluded.expires_at, + synced_at = excluded.synced_at, + role = CASE + WHEN excluded.role IN ('admin', 'member') THEN excluded.role + WHEN excluded.role = 'visitor' AND web_area_permissions.role IN ('admin', 'member') THEN web_area_permissions.role + ELSE excluded.role + END"); foreach ($perms as $p) { $stmt->bindValue(':land_id', (int)($p['land_id'] ?? 0), SQLITE3_INTEGER); diff --git a/api/sync.php b/api/sync.php index 3914df9..a818469 100644 --- a/api/sync.php +++ b/api/sync.php @@ -681,9 +681,22 @@ function syncPermissions() { )"); $now = time(); - $stmt = $db->prepare("INSERT OR REPLACE INTO web_area_permissions + // ★ 用 ON CONFLICT 替代 INSERT OR REPLACE,避免角色降级: + // 如果已有管理员/成员角色,不接受被降级为访客 + $stmt = $db->prepare("INSERT INTO web_area_permissions (land_id, land_name, player_name, role, permissions, granted_at, expires_at, synced_at) - VALUES (:land_id, :land_name, :player, :role, :perms, :granted, :expires, :synced)"); + VALUES (:land_id, :land_name, :player, :role, :perms, :granted, :expires, :synced) + ON CONFLICT(land_id, player_name) DO UPDATE SET + land_name = excluded.land_name, + permissions = excluded.permissions, + granted_at = excluded.granted_at, + expires_at = excluded.expires_at, + synced_at = excluded.synced_at, + role = CASE + WHEN excluded.role IN ('admin', 'member') THEN excluded.role + WHEN excluded.role = 'visitor' AND web_area_permissions.role IN ('admin', 'member') THEN web_area_permissions.role + ELSE excluded.role + END"); $count = 0; foreach ($perms as $p) { $stmt->bindValue(':land_id', (int)($p['land_id'] ?? 0), SQLITE3_INTEGER);