feat: 用户组同步+管理API (sync_user_groups, land_api endpoints)
This commit is contained in:
@@ -307,6 +307,32 @@ try {
|
||||
handleAckAdminChanges($db, $_POST + $_GET);
|
||||
break;
|
||||
|
||||
// ===== 用户组管理 =====
|
||||
case 'list_user_groups':
|
||||
handleListUserGroups($db);
|
||||
break;
|
||||
case 'get_user_group':
|
||||
handleGetUserGroup($db, $_GET['name'] ?? '');
|
||||
break;
|
||||
case 'update_user_group':
|
||||
handleUpdateUserGroup($db, $_POST + $_GET);
|
||||
break;
|
||||
case 'delete_user_group':
|
||||
handleDeleteUserGroup($db, $_GET['name'] ?? '');
|
||||
break;
|
||||
case 'list_group_members':
|
||||
handleListGroupMembers($db, $_GET['group'] ?? '');
|
||||
break;
|
||||
case 'add_group_member':
|
||||
handleAddGroupMember($db, $_POST + $_GET);
|
||||
break;
|
||||
case 'remove_group_member':
|
||||
handleRemoveGroupMember($db, $_POST + $_GET);
|
||||
break;
|
||||
case 'get_player_groups':
|
||||
handleGetPlayerGroups($db, $_GET['player'] ?? '');
|
||||
break;
|
||||
|
||||
default:
|
||||
echo json_encode(['success' => false, 'error' => 'unknown action']);
|
||||
}
|
||||
@@ -1415,6 +1441,177 @@ function handleAckAdminChanges($db, $post) {
|
||||
echo json_encode(['success' => true, 'acked' => count($idList)]);
|
||||
}
|
||||
|
||||
// ===== 用户组管理函数 =====
|
||||
|
||||
function handleListUserGroups($db) {
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_groups (
|
||||
group_name TEXT PRIMARY KEY,
|
||||
display_name TEXT DEFAULT '',
|
||||
display_color TEXT DEFAULT '§f',
|
||||
display_emoji TEXT DEFAULT '',
|
||||
priority INTEGER DEFAULT 0,
|
||||
land_price_per_sqm INTEGER DEFAULT -1,
|
||||
max_lands INTEGER DEFAULT -1,
|
||||
default_perms TEXT DEFAULT '{}',
|
||||
synced_at INTEGER DEFAULT 0
|
||||
)");
|
||||
$rs = $db->query("SELECT * FROM web_user_groups ORDER BY priority DESC");
|
||||
$groups = [];
|
||||
while ($row = $rs->fetchArray(SQLITE3_ASSOC)) {
|
||||
$groups[] = $row;
|
||||
}
|
||||
echo json_encode(['success' => true, 'groups' => $groups]);
|
||||
}
|
||||
|
||||
function handleGetUserGroup($db, $name) {
|
||||
if (empty($name)) { echo json_encode(['success' => false, 'error' => 'missing name']); return; }
|
||||
$stmt = $db->prepare("SELECT * FROM web_user_groups WHERE group_name = :name");
|
||||
$stmt->bindValue(':name', $name, SQLITE3_TEXT);
|
||||
$rs = $stmt->execute();
|
||||
$row = $rs->fetchArray(SQLITE3_ASSOC);
|
||||
if (!$row) { echo json_encode(['success' => false, 'error' => 'group not found']); return; }
|
||||
echo json_encode(['success' => true, 'group' => $row]);
|
||||
}
|
||||
|
||||
function handleUpdateUserGroup($db, $data) {
|
||||
$name = $data['name'] ?? $data['group_name'] ?? '';
|
||||
if (empty($name)) { echo json_encode(['success' => false, 'error' => 'missing name']); return; }
|
||||
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_groups (
|
||||
group_name TEXT PRIMARY KEY,
|
||||
display_name TEXT DEFAULT '',
|
||||
display_color TEXT DEFAULT '§f',
|
||||
display_emoji TEXT DEFAULT '',
|
||||
priority INTEGER DEFAULT 0,
|
||||
land_price_per_sqm INTEGER DEFAULT -1,
|
||||
max_lands INTEGER DEFAULT -1,
|
||||
default_perms TEXT DEFAULT '{}',
|
||||
synced_at INTEGER DEFAULT 0
|
||||
)");
|
||||
|
||||
$displayName = $data['display_name'] ?? '';
|
||||
$displayColor = $data['display_color'] ?? '§f';
|
||||
$displayEmoji = $data['display_emoji'] ?? '';
|
||||
$priority = (int)($data['priority'] ?? 0);
|
||||
$pricePerSqm = (int)($data['land_price_per_sqm'] ?? -1);
|
||||
$maxLands = (int)($data['max_lands'] ?? -1);
|
||||
$defaultPerms = $data['default_perms'] ?? '{}';
|
||||
|
||||
$stmt = $db->prepare("INSERT OR REPLACE INTO web_user_groups
|
||||
(group_name, display_name, display_color, display_emoji, priority,
|
||||
land_price_per_sqm, max_lands, default_perms, synced_at)
|
||||
VALUES (:name, :display, :color, :emoji, :priority,
|
||||
:price, :maxlands, :perms, :synced)");
|
||||
$stmt->bindValue(':name', $name, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':display', $displayName, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':color', $displayColor, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':emoji', $displayEmoji, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':priority', $priority, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':price', $pricePerSqm, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':maxlands', $maxLands, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':perms', $defaultPerms, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':synced', time(), SQLITE3_INTEGER);
|
||||
$stmt->execute();
|
||||
echo json_encode(['success' => true, 'message' => "用户组 {$name} 已更新"]);
|
||||
}
|
||||
|
||||
function handleDeleteUserGroup($db, $name) {
|
||||
if (empty($name)) { echo json_encode(['success' => false, 'error' => 'missing name']); return; }
|
||||
$stmt = $db->prepare("DELETE FROM web_user_groups WHERE group_name = :name");
|
||||
$stmt->bindValue(':name', $name, SQLITE3_TEXT);
|
||||
$stmt->execute();
|
||||
echo json_encode(['success' => true, 'message' => "用户组 {$name} 已删除"]);
|
||||
}
|
||||
|
||||
function handleListGroupMembers($db, $group) {
|
||||
if (empty($group)) { echo json_encode(['success' => false, 'error' => 'missing group']); return; }
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_group_members (
|
||||
player_name TEXT NOT NULL,
|
||||
group_name TEXT NOT NULL,
|
||||
added_by TEXT DEFAULT 'system',
|
||||
added_time INTEGER DEFAULT 0,
|
||||
expiry_time INTEGER DEFAULT 0,
|
||||
PRIMARY KEY(player_name, group_name)
|
||||
)");
|
||||
$stmt = $db->prepare("SELECT * FROM web_user_group_members WHERE group_name = :group");
|
||||
$stmt->bindValue(':group', $group, SQLITE3_TEXT);
|
||||
$rs = $stmt->execute();
|
||||
$members = [];
|
||||
while ($row = $rs->fetchArray(SQLITE3_ASSOC)) {
|
||||
$members[] = $row;
|
||||
}
|
||||
echo json_encode(['success' => true, 'members' => $members]);
|
||||
}
|
||||
|
||||
function handleAddGroupMember($db, $data) {
|
||||
$player = $data['player'] ?? $data['player_name'] ?? '';
|
||||
$group = $data['group'] ?? $data['group_name'] ?? '';
|
||||
if (empty($player) || empty($group)) {
|
||||
echo json_encode(['success' => false, 'error' => 'missing player or group']);
|
||||
return;
|
||||
}
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_group_members (
|
||||
player_name TEXT NOT NULL,
|
||||
group_name TEXT NOT NULL,
|
||||
added_by TEXT DEFAULT 'system',
|
||||
added_time INTEGER DEFAULT 0,
|
||||
expiry_time INTEGER DEFAULT 0,
|
||||
PRIMARY KEY(player_name, group_name)
|
||||
)");
|
||||
$addedBy = $data['added_by'] ?? 'admin';
|
||||
$now = time();
|
||||
$expiry = (int)($data['expiry_time'] ?? 0);
|
||||
|
||||
$stmt = $db->prepare("INSERT OR REPLACE INTO web_user_group_members
|
||||
(player_name, group_name, added_by, added_time, expiry_time)
|
||||
VALUES (:player, :group, :addedby, :added, :expiry)");
|
||||
$stmt->bindValue(':player', $player, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':group', $group, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':addedby', $addedBy, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':added', $now, SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':expiry', $expiry, SQLITE3_INTEGER);
|
||||
$stmt->execute();
|
||||
|
||||
echo json_encode(['success' => true, 'message' => "{$player} 已加入用户组 {$group}"]);
|
||||
}
|
||||
|
||||
function handleRemoveGroupMember($db, $data) {
|
||||
$player = $data['player'] ?? $data['player_name'] ?? '';
|
||||
$group = $data['group'] ?? $data['group_name'] ?? '';
|
||||
if (empty($player) || empty($group)) {
|
||||
echo json_encode(['success' => false, 'error' => 'missing player or group']);
|
||||
return;
|
||||
}
|
||||
$stmt = $db->prepare("DELETE FROM web_user_group_members WHERE player_name = :player AND group_name = :group");
|
||||
$stmt->bindValue(':player', $player, SQLITE3_TEXT);
|
||||
$stmt->bindValue(':group', $group, SQLITE3_TEXT);
|
||||
$stmt->execute();
|
||||
echo json_encode(['success' => true, 'message' => "{$player} 已移出用户组 {$group}"]);
|
||||
}
|
||||
|
||||
function handleGetPlayerGroups($db, $player) {
|
||||
if (empty($player)) { echo json_encode(['success' => false, 'error' => 'missing player']); return; }
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_group_members (
|
||||
player_name TEXT NOT NULL,
|
||||
group_name TEXT NOT NULL,
|
||||
added_by TEXT DEFAULT 'system',
|
||||
added_time INTEGER DEFAULT 0,
|
||||
expiry_time INTEGER DEFAULT 0,
|
||||
PRIMARY KEY(player_name, group_name)
|
||||
)");
|
||||
$stmt = $db->prepare("SELECT m.*, g.display_name, g.display_color, g.priority
|
||||
FROM web_user_group_members m
|
||||
LEFT JOIN web_user_groups g ON m.group_name = g.group_name
|
||||
WHERE m.player_name = :player");
|
||||
$stmt->bindValue(':player', $player, SQLITE3_TEXT);
|
||||
$rs = $stmt->execute();
|
||||
$groups = [];
|
||||
while ($row = $rs->fetchArray(SQLITE3_ASSOC)) {
|
||||
$groups[] = $row;
|
||||
}
|
||||
echo json_encode(['success' => true, 'groups' => $groups]);
|
||||
}
|
||||
|
||||
function validateSecret($secret) {
|
||||
if (empty($secret)) return false;
|
||||
$validSecrets = [
|
||||
|
||||
@@ -312,6 +312,9 @@ switch ($action) {
|
||||
case 'sync_permissions':
|
||||
syncPermissions();
|
||||
break;
|
||||
case 'sync_user_groups':
|
||||
syncUserGroups();
|
||||
break;
|
||||
default:
|
||||
error('未知操作: ' . $action);
|
||||
}
|
||||
@@ -678,6 +681,88 @@ function syncPermissions() {
|
||||
success("访客权限同步成功: {$count}个");
|
||||
}
|
||||
|
||||
// ===== 用户组同步 =====
|
||||
function syncUserGroups() {
|
||||
$secret = getParam('secret');
|
||||
if ($secret !== SECRET_KEY) error('密钥验证失败', 403);
|
||||
|
||||
$groupsRaw = getParam('groups');
|
||||
if (!$groupsRaw) error('缺少groups参数');
|
||||
$groups = is_array($groupsRaw) ? $groupsRaw : json_decode($groupsRaw, true);
|
||||
if (!is_array($groups)) error('groups格式无效');
|
||||
|
||||
$db = getDB();
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_groups (
|
||||
group_name TEXT PRIMARY KEY,
|
||||
display_name TEXT DEFAULT '',
|
||||
display_color TEXT DEFAULT '§f',
|
||||
display_emoji TEXT DEFAULT '',
|
||||
priority INTEGER DEFAULT 0,
|
||||
land_price_per_sqm INTEGER DEFAULT -1,
|
||||
max_lands INTEGER DEFAULT -1,
|
||||
default_perms TEXT DEFAULT '{}',
|
||||
synced_at INTEGER DEFAULT 0
|
||||
)");
|
||||
|
||||
$now = time();
|
||||
$stmt = $db->prepare("INSERT OR REPLACE INTO web_user_groups
|
||||
(group_name, display_name, display_color, display_emoji, priority,
|
||||
land_price_per_sqm, max_lands, default_perms, synced_at)
|
||||
VALUES (:name, :display, :color, :emoji, :priority,
|
||||
:price, :maxlands, :perms, :synced)");
|
||||
$count = 0;
|
||||
foreach ($groups as $g) {
|
||||
$stmt->bindValue(':name', $g['group_name'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':display', $g['display_name'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':color', $g['display_color'] ?? '§f', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':emoji', $g['display_emoji'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':priority', (int)($g['priority'] ?? 0), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':price', (int)($g['land_price_per_sqm'] ?? -1), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':maxlands', (int)($g['max_lands'] ?? -1), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':perms', $g['default_perms'] ?? '{}', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':synced', $now, SQLITE3_INTEGER);
|
||||
$stmt->execute();
|
||||
$count++;
|
||||
}
|
||||
success("用户组同步成功: {$count}个");
|
||||
}
|
||||
|
||||
// ===== 用户组成员同步 =====
|
||||
function syncUserGroupMembers() {
|
||||
$secret = getParam('secret');
|
||||
if ($secret !== SECRET_KEY) error('密钥验证失败', 403);
|
||||
|
||||
$membersRaw = getParam('members');
|
||||
if (!$membersRaw) error('缺少members参数');
|
||||
$members = is_array($membersRaw) ? $membersRaw : json_decode($membersRaw, true);
|
||||
if (!is_array($members)) error('members格式无效');
|
||||
|
||||
$db = getDB();
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_user_group_members (
|
||||
player_name TEXT NOT NULL,
|
||||
group_name TEXT NOT NULL,
|
||||
added_by TEXT DEFAULT 'system',
|
||||
added_time INTEGER DEFAULT 0,
|
||||
expiry_time INTEGER DEFAULT 0,
|
||||
PRIMARY KEY(player_name, group_name)
|
||||
)");
|
||||
|
||||
$stmt = $db->prepare("INSERT OR REPLACE INTO web_user_group_members
|
||||
(player_name, group_name, added_by, added_time, expiry_time)
|
||||
VALUES (:player, :group, :addedby, :added, :expiry)");
|
||||
$count = 0;
|
||||
foreach ($members as $m) {
|
||||
$stmt->bindValue(':player', $m['player_name'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':group', $m['group_name'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':addedby', $m['added_by'] ?? 'system', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':added', (int)($m['added_time'] ?? 0), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':expiry', (int)($m['expiry_time'] ?? 0), SQLITE3_INTEGER);
|
||||
$stmt->execute();
|
||||
$count++;
|
||||
}
|
||||
success("用户组成员同步成功: {$count}条");
|
||||
}
|
||||
|
||||
// ===== 插件推送债券余额 =====
|
||||
function syncBonds() {
|
||||
// ★ 支持token或SECRET_KEY认证
|
||||
|
||||
Reference in New Issue
Block a user