497 lines
23 KiB
PHP
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);
|
|
?>
|