Autosave: 20260220-073954

This commit is contained in:
Flatlogic Bot 2026-02-20 07:39:54 +00:00
parent abd41c080c
commit 88f258181d
18 changed files with 826 additions and 376 deletions

View File

@ -87,7 +87,7 @@ $controls = $db->query("SELECT * FROM price_controls ORDER BY execution_time DES
<td><strong><?= $c['symbol'] ?></strong></td>
<td class="text-primary fw-bold"><?= $c['target_price'] ?></td>
<td><?= $c['execution_time'] ?></td>
<td><?= $c['duration'] ?>s</td>
<td><?= $c['duration'] ?></td>
<td>
<?php if (strtotime($c['execution_time']) > time()): ?>
<span class="badge bg-warning">待执行</span>

View File

@ -97,6 +97,16 @@ ob_start();
.msg-user .msg-time {
color: #888;
}
.recall-btn {
font-size: 10px;
text-decoration: underline;
cursor: pointer;
opacity: 0;
transition: opacity 0.2s;
}
.msg-admin:hover .recall-btn {
opacity: 1;
}
.chat-input-area {
padding: 15px;
border-top: 1px solid #eee;
@ -147,6 +157,7 @@ ob_start();
<div>
<span class="status-online"></span>
<span class="small text-success">在线</span>
<button class="btn btn-link btn-sm text-danger text-decoration-none ms-2" onclick="deleteUser()"><i class="bi bi-trash"></i> 删除用户</button>
</div>
</div>
</div>
@ -254,6 +265,40 @@ function openChat(userId, ip, name, uid, remark, userTime) {
refreshUsers(); // Refresh list to update active state
}
async function recallMessage(msgId) {
if (!confirm('确定撤回该消息吗?')) return;
const fd = new URLSearchParams();
fd.append('message_id', msgId);
const r = await fetch('/api/chat.php?action=admin_recall_message', { method: 'POST', body: fd });
const res = await r.json();
if (res.success) {
fetchMessages();
}
}
async function deleteUser() {
if (!confirm('确定删除该用户的所有聊天记录吗?此操作不可恢复!')) return;
const fd = new URLSearchParams();
fd.append('user_id', selectedUser);
fd.append('ip_address', selectedIp);
const r = await fetch('/api/chat.php?action=admin_delete_user', { method: 'POST', body: fd });
const res = await r.json();
if (res.success) {
selectedUser = null;
selectedIp = null;
document.getElementById('chat-header').style.display = 'none';
document.getElementById('input-area').style.display = 'none';
document.getElementById('remark-area').style.display = 'none';
document.getElementById('messages-area').innerHTML = `
<div class="m-auto text-center text-muted">
<i class="bi bi-chat-left-dots fs-1 d-block mb-2"></i>
<p>请从左侧选择一个会话</p>
</div>
`;
refreshUsers();
}
}
async function fetchMessages() {
if (!selectedIp && !selectedUser) return;
const r = await fetch(`/api/chat.php?action=get_messages&user_id=${selectedUser}&ip=${selectedIp}`);
@ -276,10 +321,13 @@ async function fetchMessages() {
filtered.forEach(m => {
const msgDate = new Date(m.created_at.replace(/-/g, "/"));
const timeStr = msgDate.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit', second: '2-digit'});
const recallHtml = m.sender === 'admin' ? `<span class="recall-btn text-white-50" onclick="recallMessage(${m.id})">撤回</span>` : '';
const isImage = m.message.indexOf('<img') !== -1;
html += `
<div class="msg ${m.sender === 'admin' ? 'msg-admin' : 'msg-user'}">
<div class="msg ${m.sender === 'admin' ? 'msg-admin' : 'msg-user'}" style="${isImage ? 'padding: 5px; background: ' + (m.sender === 'admin' ? '#007bff' : '#f0f0f0') + ';' : ''}">
<div class="msg-content">${m.message}</div>
<div class="msg-time">${timeStr}</div>
<div class="msg-time" style="${isImage ? 'position: absolute; bottom: 4px; right: 10px; background: rgba(0,0,0,0.3); color: #fff; padding: 0 4px; border-radius: 4px;' : ''}">${timeStr} ${recallHtml}</div>
</div>
`;
});

View File

@ -106,7 +106,7 @@ if ($user_id) {
<td><code><?= $u['uid'] ?></code></td>
<td><?= htmlspecialchars($u['kyc_name'] ?? '---') ?></td>
<td><?= htmlspecialchars($u['kyc_id_number'] ?? '---') ?></td>
<td><span class="text-muted small">Global</span></td>
<td><span class="text-muted small">全球</span></td>
<td>
<img src="<?= $u['kyc_photo_front'] ? (strpos($u['kyc_photo_front'], 'http') === 0 ? $u['kyc_photo_front'] : '/' . ltrim($u['kyc_photo_front'], '/')) : 'https://via.placeholder.com/100x70?text=No+Photo' ?>"
class="rounded border cursor-zoom-in" style="width: 60px; height: 40px; object-fit: cover;"

View File

@ -3,8 +3,9 @@ require_once __DIR__ . '/../db/config.php';
require_once __DIR__ . '/../includes/lang.php';
if (session_status() === PHP_SESSION_NONE) session_start();
// Use site default language
$lang = $_SESSION['lang'] ?? 'en';
// Force simplified Chinese for admin
$lang = 'zh';
$_SESSION['lang'] = 'zh';
// Admin check
$admin = null;

View File

@ -13,7 +13,7 @@ if (isset($_SESSION['admin_id'])) {
// Get site settings
$site_logo = getSetting('site_logo', '/assets/images/logo.png');
$site_favicon = getSetting('site_favicon', $site_logo);
$site_name = getSetting('site_name', 'Byro') . ' Admin';
$site_name = getSetting('site_name', 'Byro') . ' 管理后台';
$error = '';

View File

@ -29,7 +29,7 @@ if ($action === 'upload_image' || (isset($_POST['action']) && $_POST['action'] =
if (move_uploaded_file($file['tmp_name'], $targetPath)) {
$imageUrl = '/assets/images/chat/' . $filename;
$message = '<img src="' . $imageUrl . '" class="img-fluid rounded cursor-pointer" style="max-width: 200px; max-height: 200px;" onclick="window.open(\'' . $imageUrl . '\')">';
$message = '<img src="' . $imageUrl . '" class="img-fluid rounded cursor-pointer" style="max-width: 100%; max-height: 250px; object-fit: contain; margin: 5px 0;" onclick="window.open(\'' . $imageUrl . '\')">';
if (isset($_SESSION['admin_id'])) {
$user_id = $_POST['user_id'] ?? 0;
@ -114,47 +114,38 @@ if ($action === 'ping') {
}
if ($action === 'admin_get_all') {
// Get distinct users (prefer user_id, fallback to IP if user_id is 0)
// Registered users are grouped by user_id. Anonymous users are grouped by ip_address.
$stmt = db()->query("
SELECT
combined.group_user_id as user_id,
combined.display_ip as ip_address,
COALESCE(m.message, '用户已进入聊天室') as message,
COALESCE(m.created_at, combined.last_activity) as created_at,
u.username,
v.user_id,
v.ip_address,
CASE WHEN m.message LIKE '<img%' THEN '[图片]' ELSE COALESCE(m.message, '用户已进入聊天室') END as message,
COALESCE(m.created_at, v.last_activity) as created_at,
CASE WHEN u.email LIKE '%@user.byro' THEN u.username ELSE COALESCE(u.email, u.username) END as username,
u.uid,
r.remark,
combined.user_time
v.user_time
FROM (
SELECT
user_id as group_user_id,
CASE WHEN user_id = 0 THEN ip_address ELSE '0' END as group_id,
MAX(ip_address) as display_ip,
MAX(created_at) as last_activity,
NULL as user_time
FROM messages
GROUP BY group_user_id, group_id
UNION
SELECT
user_id as group_user_id,
CASE WHEN user_id = 0 THEN ip_address ELSE '0' END as group_id,
MAX(ip_address) as display_ip,
MAX(last_ping) as last_activity,
user_id,
MAX(ip_address) as ip_address,
MAX(last_activity) as last_activity,
MAX(user_time) as user_time
FROM chat_visitors
GROUP BY group_user_id, group_id
) combined
FROM (
SELECT user_id, ip_address, MAX(created_at) as last_activity, NULL as user_time FROM messages GROUP BY user_id, ip_address
UNION
SELECT user_id, ip_address, MAX(last_ping) as last_activity, MAX(user_time) as user_time FROM chat_visitors GROUP BY user_id, ip_address
) t1
GROUP BY user_id, (CASE WHEN user_id = 0 THEN ip_address ELSE '0' END)
) v
LEFT JOIN (
SELECT id, user_id, ip_address, message, created_at FROM messages
WHERE id IN (
SELECT MAX(id) FROM messages GROUP BY user_id, (CASE WHEN user_id = 0 THEN ip_address ELSE '0' END)
)
) m ON (combined.group_user_id = m.user_id AND (combined.group_user_id != 0 OR combined.display_ip = m.ip_address))
LEFT JOIN users u ON (combined.group_user_id = u.id AND combined.group_user_id != 0)
LEFT JOIN chat_remarks r ON (combined.group_user_id = r.user_id AND (combined.group_user_id != 0 OR combined.display_ip = r.ip_address))
WHERE combined.last_activity > DATE_SUB(NOW(), INTERVAL 48 HOUR)
GROUP BY combined.group_user_id, combined.display_ip
SELECT m1.* FROM messages m1
INNER JOIN (
SELECT MAX(id) as max_id FROM messages GROUP BY user_id, (CASE WHEN user_id = 0 THEN ip_address ELSE '0' END)
) m2 ON m1.id = m2.max_id
) m ON (v.user_id = m.user_id AND (v.user_id != 0 OR v.ip_address = m.ip_address))
LEFT JOIN users u ON (v.user_id = u.id AND v.user_id != 0)
LEFT JOIN chat_remarks r ON (v.user_id = r.user_id AND (v.user_id != 0 OR v.ip_address = r.ip_address))
WHERE v.last_activity > DATE_SUB(NOW(), INTERVAL 48 HOUR)
ORDER BY created_at DESC
");
echo json_encode($stmt->fetchAll());
@ -188,3 +179,36 @@ if ($action === 'get_remark') {
echo json_encode(['success' => true, 'remark' => $remark]);
exit;
}
if ($action === 'admin_delete_user') {
if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized']));
$user_id = $_POST['user_id'] ?? 0;
$ip = $_POST['ip_address'] ?? '';
if ($user_id != 0) {
$stmt = db()->prepare("DELETE FROM messages WHERE user_id = ?");
$stmt->execute([$user_id]);
$stmt = db()->prepare("DELETE FROM chat_visitors WHERE user_id = ?");
$stmt->execute([$user_id]);
$stmt = db()->prepare("DELETE FROM chat_remarks WHERE user_id = ?");
$stmt->execute([$user_id]);
} else {
$stmt = db()->prepare("DELETE FROM messages WHERE user_id = 0 AND ip_address = ?");
$stmt->execute([$ip]);
$stmt = db()->prepare("DELETE FROM chat_visitors WHERE user_id = 0 AND ip_address = ?");
$stmt->execute([$ip]);
$stmt = db()->prepare("DELETE FROM chat_remarks WHERE user_id = 0 AND ip_address = ?");
$stmt->execute([$ip]);
}
echo json_encode(['success' => true]);
exit;
}
if ($action === 'admin_recall_message') {
if (!isset($_SESSION['admin_id'])) exit(json_encode(['success' => false, 'error' => 'Unauthorized']));
$message_id = $_POST['message_id'] ?? 0;
$stmt = db()->prepare("DELETE FROM messages WHERE id = ? AND sender = 'admin'");
$stmt->execute([$message_id]);
echo json_encode(['success' => true]);
exit;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -40,7 +40,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($reg_type === 'email') {
$email = $account;
$username = explode('@', $account)[0];
$username = $account;
} else {
$email = $username . '@user.byro'; // Fallback
}

View File

@ -1,320 +0,0 @@
/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19 Distrib 10.11.14-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: 127.0.0.1 Database: app_38451
-- ------------------------------------------------------
-- Server version 10.11.14-MariaDB-0+deb12u2
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
SET FOREIGN_KEY_CHECKS = 0;
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
CREATE TABLE `admins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password_hash` varchar(255) NOT NULL,
`role` varchar(20) DEFAULT 'admin',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`is_agent` tinyint(4) DEFAULT 0,
`permissions` text DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `admins` (`id`, `username`, `password_hash`, `role`) VALUES (1,'admin','$2y$10$uJvcqHNb.naRWj.apBapi.C.fF2zaIbMhYEtVdGmmVUWZkQi9ESfe','admin');
--
-- Table structure for table `binary_orders`
--
DROP TABLE IF EXISTS `binary_orders`;
CREATE TABLE `binary_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(20) NOT NULL,
`direction` varchar(10) DEFAULT NULL,
`amount` decimal(20,8) NOT NULL,
`duration` int(11) NOT NULL,
`profit_rate` decimal(5,2) NOT NULL,
`entry_price` decimal(20,8) NOT NULL,
`close_price` decimal(20,8) DEFAULT NULL,
`status` enum('pending','won','lost','cancelled') DEFAULT 'pending',
`control_status` tinyint(4) DEFAULT 0,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`end_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `contract_orders`
--
DROP TABLE IF EXISTS `contract_orders`;
CREATE TABLE `contract_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(20) NOT NULL,
`type` enum('limit','market') DEFAULT 'market',
`direction` varchar(10) DEFAULT NULL,
`leverage` int(11) DEFAULT 1,
`amount` decimal(20,8) NOT NULL,
`entry_price` decimal(20,8) DEFAULT NULL,
`close_price` decimal(20,8) DEFAULT NULL,
`status` enum('open','closed','cancelled') DEFAULT 'open',
`profit` decimal(20,8) DEFAULT 0.00000000,
`control_status` tinyint(4) DEFAULT 0,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `exchange_records`
--
DROP TABLE IF EXISTS `exchange_records`;
CREATE TABLE `exchange_records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`from_symbol` varchar(10) NOT NULL,
`to_symbol` varchar(10) NOT NULL,
`from_amount` decimal(20,8) NOT NULL,
`to_amount` decimal(20,8) NOT NULL,
`rate` decimal(20,8) NOT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `finance_requests`
--
DROP TABLE IF EXISTS `finance_requests`;
CREATE TABLE `finance_requests` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`type` enum('recharge','withdrawal') NOT NULL,
`amount` decimal(20,8) NOT NULL,
`symbol` varchar(10) DEFAULT 'USDT',
`status` enum('pending','approved','rejected') DEFAULT 'pending',
`payment_method` varchar(50) DEFAULT NULL,
`payment_details` text DEFAULT NULL,
`rejection_reason` text DEFAULT NULL,
`tx_hash` varchar(255) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`fiat_amount` decimal(20,2) DEFAULT NULL,
`fiat_currency` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `messages`
--
DROP TABLE IF EXISTS `messages`;
CREATE TABLE `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`admin_id` int(11) DEFAULT NULL,
`sender` enum('user','admin') DEFAULT NULL,
`message` text DEFAULT NULL,
`ip_address` varchar(45) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `price_controls`
--
DROP TABLE IF EXISTS `price_controls`;
CREATE TABLE `price_controls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`symbol` varchar(20) NOT NULL,
`target_price` decimal(20,8) NOT NULL,
`execution_time` timestamp NOT NULL,
`duration` int(11) DEFAULT 60,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `spot_orders`
--
DROP TABLE IF EXISTS `spot_orders`;
CREATE TABLE `spot_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(20) NOT NULL,
`side` enum('buy','sell') NOT NULL,
`price` decimal(20,8) DEFAULT NULL,
`amount` decimal(20,8) NOT NULL,
`filled` decimal(20,8) DEFAULT 0.00000000,
`status` enum('pending','filled','cancelled') DEFAULT 'pending',
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `staking_records`
--
DROP TABLE IF EXISTS `staking_records`;
CREATE TABLE `staking_records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`plan_name` varchar(100) NOT NULL,
`amount` decimal(20,8) NOT NULL,
`symbol` varchar(10) DEFAULT 'USDT',
`daily_profit` decimal(5,2) NOT NULL,
`period` int(11) NOT NULL,
`status` enum('running','ended') DEFAULT 'running',
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `system_settings`
--
DROP TABLE IF EXISTS `system_settings`;
CREATE TABLE `system_settings` (
`setting_key` varchar(50) NOT NULL,
`setting_value` text DEFAULT NULL,
PRIMARY KEY (`setting_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `system_settings` VALUES
('android_download_url','/downloads/byro.apk'),
('apk_download_url','/downloads/byro.apk'),
('email_verification_enabled','0'),
('ios_download_url','/downloads/byro.apk'),
('mail_from_email',''),
('mail_from_name','Byro Exchange'),
('service_link',''),
('site_logo','/assets/pasted-20260219-011659-0f2b767b.png'),
('site_name','Byro'),
('smtp_host',''),
('smtp_pass',''),
('smtp_port','587'),
('smtp_secure','tls'),
('smtp_user',''),
('usdt_bep20_address','0x742d35Cc6634C0532925a3b844Bc454e4438f44e'),
('usdt_erc20_address','0x742d35Cc6634C0532925a3b844Bc454e4438f44e'),
('usdt_protocol','TRC20'),
('usdt_recharge_address',''),
('usdt_trc20_address','TYv9V5J1P1eEwz7y3WqJg9M2yv7f7xXv3x');
--
-- Table structure for table `transactions`
--
DROP TABLE IF EXISTS `transactions`;
CREATE TABLE `transactions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`type` varchar(20) NOT NULL,
`amount` decimal(20,8) NOT NULL,
`symbol` varchar(10) NOT NULL,
`status` varchar(20) DEFAULT 'completed',
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `user_balances`
--
DROP TABLE IF EXISTS `user_balances`;
CREATE TABLE `user_balances` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(10) NOT NULL,
`available` decimal(20,8) DEFAULT 0.00000000,
`frozen` decimal(20,8) DEFAULT 0.00000000,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`symbol`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`password_hash` varchar(255) NOT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`uid` varchar(20) DEFAULT NULL,
`credit_score` int(11) DEFAULT 80,
`real_name_status` int(11) DEFAULT 0,
`role` varchar(20) DEFAULT 'user',
`vip_level` int(11) DEFAULT 0,
`total_recharge` decimal(16,4) DEFAULT 0.0000,
`transaction_password` varchar(255) DEFAULT NULL,
`kyc_name` varchar(100) DEFAULT NULL,
`kyc_id_number` varchar(50) DEFAULT NULL,
`kyc_photo_front` varchar(255) DEFAULT NULL,
`kyc_photo_back` varchar(255) DEFAULT NULL,
`kyc_photo_handheld` varchar(255) DEFAULT NULL,
`kyc_status` int(11) DEFAULT 0,
`registration_ip` varchar(45) DEFAULT NULL,
`status` enum('normal','frozen') DEFAULT 'normal',
`win_loss_control` tinyint(4) DEFAULT 0,
`remark` text DEFAULT NULL,
`kyc_rejection_reason` text DEFAULT NULL,
`agent_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `mining_orders`
--
DROP TABLE IF EXISTS `mining_orders`;
CREATE TABLE `mining_orders` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`user_id` INT NOT NULL,
`symbol` VARCHAR(10) NOT NULL,
`pool_name` VARCHAR(100) NOT NULL,
`amount` DECIMAL(20, 8) NOT NULL,
`apy` DECIMAL(10, 4) NOT NULL,
`period` VARCHAR(20) NOT NULL,
`status` VARCHAR(20) DEFAULT 'running',
`start_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`end_time` DATETIME,
`last_payout` DATETIME DEFAULT CURRENT_TIMESTAMP,
`total_profit` DECIMAL(20, 8) DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `chat_visitors`
--
DROP TABLE IF EXISTS `chat_visitors`;
CREATE TABLE `chat_visitors` (
`user_id` int(11) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`last_ping` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`user_id`,`ip_address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
-- Table structure for table `chat_remarks`
--
DROP TABLE IF EXISTS `chat_remarks`;
CREATE TABLE `chat_remarks` (
`user_id` int(11) NOT NULL,
`ip_address` varchar(45) NOT NULL,
`remark` text DEFAULT NULL,
PRIMARY KEY (`user_id`,`ip_address`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SET FOREIGN_KEY_CHECKS = 1;

680
db/database.sql Normal file
View File

@ -0,0 +1,680 @@
/*M!999999\- enable the sandbox mode */
-- MariaDB dump 10.19 Distrib 10.11.14-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: 127.0.0.1 Database: app_38451
-- ------------------------------------------------------
-- Server version 10.11.14-MariaDB-0+deb12u2
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `admins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password_hash` varchar(255) NOT NULL,
`role` varchar(20) DEFAULT 'admin',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`is_agent` tinyint(4) DEFAULT 0,
`permissions` text DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `admins`
--
LOCK TABLES `admins` WRITE;
/*!40000 ALTER TABLE `admins` DISABLE KEYS */;
INSERT INTO `admins` VALUES
(1,'admin','$2y$10$uJvcqHNb.naRWj.apBapi.C.fF2zaIbMhYEtVdGmmVUWZkQi9ESfe','admin','2026-02-18 03:07:35',0,NULL);
/*!40000 ALTER TABLE `admins` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `binary_orders`
--
DROP TABLE IF EXISTS `binary_orders`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `binary_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(20) NOT NULL,
`direction` varchar(10) DEFAULT NULL,
`amount` decimal(20,8) NOT NULL,
`duration` int(11) NOT NULL,
`profit_rate` decimal(5,2) NOT NULL,
`entry_price` decimal(20,8) NOT NULL,
`close_price` decimal(20,8) DEFAULT NULL,
`status` enum('pending','won','lost','cancelled') DEFAULT 'pending',
`control_status` tinyint(4) DEFAULT 0 COMMENT '0: normal, 1: force win, 2: force loss',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
`end_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `binary_orders`
--
LOCK TABLES `binary_orders` WRITE;
/*!40000 ALTER TABLE `binary_orders` DISABLE KEYS */;
INSERT INTO `binary_orders` VALUES
(1,2,'BTC','up',100.00000000,60,8.00,67652.01000000,68328.53010000,'won',1,'2026-02-18 06:00:25',NULL,'2026-02-18 08:00:59'),
(2,2,'BTC','down',100.00000000,60,8.00,67788.80000000,67110.91200000,'won',1,'2026-02-18 06:16:43',NULL,'2026-02-18 08:00:59'),
(3,2,'BTC','up',1000.00000000,60,8.00,67879.37000000,68558.16370000,'won',1,'2026-02-18 06:40:10',NULL,'2026-02-18 08:00:59'),
(4,2,'BTC','up',500.00000000,60,8.00,67839.92000000,68518.31920000,'won',1,'2026-02-18 06:57:02',NULL,'2026-02-18 08:00:59'),
(5,2,'BTC','up',100.00000000,60,8.00,67813.14000000,68491.27140000,'won',1,'2026-02-18 07:07:26',NULL,'2026-02-18 08:00:59'),
(6,2,'BTC','down',100.00000000,60,8.00,67770.32000000,67092.61680000,'won',1,'2026-02-18 07:17:26',NULL,'2026-02-18 08:00:59'),
(7,2,'BTC','down',100.00000000,60,8.00,67753.40000000,67075.86600000,'won',1,'2026-02-18 07:22:09',NULL,'2026-02-18 08:00:59'),
(8,2,'BTC','up',100.00000000,60,8.00,67756.31000000,68433.87310000,'won',1,'2026-02-18 07:27:16',NULL,'2026-02-18 08:01:00'),
(9,2,'BTC','down',100.00000000,60,8.00,67798.67000000,67120.68330000,'won',1,'2026-02-18 07:33:08',NULL,'2026-02-18 08:01:00'),
(10,2,'BTC','down',100.00000000,60,8.00,68073.40000000,67392.66600000,'won',1,'2026-02-18 07:44:11',NULL,'2026-02-18 08:01:00'),
(11,2,'BTC','up',100.00000000,60,8.00,68158.35000000,68839.93350000,'won',1,'2026-02-18 07:50:39',NULL,'2026-02-18 08:01:00'),
(12,2,'BTC','up',100.00000000,60,8.00,68142.00000000,68823.42000000,'won',1,'2026-02-18 08:02:35',NULL,'2026-02-18 08:03:35'),
(13,2,'BTC','down',100.00000000,60,8.00,68175.65000000,68169.15000000,'won',1,'2026-02-18 08:37:39',NULL,'2026-02-18 08:38:40'),
(14,2,'ETH','down',1000.00000000,60,8.00,1984.92000000,1986.33000000,'won',1,'2026-02-18 15:16:13',NULL,'2026-02-18 15:17:14'),
(15,2,'BTC','down',23000.00000000,90,12.00,67240.69000000,67230.01000000,'won',2,'2026-02-19 07:22:31',NULL,'2026-02-19 07:24:01'),
(16,2,'BTC','down',1000.00000000,60,8.00,67239.99000000,66567.59010000,'won',2,'2026-02-19 07:26:33',NULL,'2026-02-19 07:27:41'),
(17,2,'BTC','down',1000.00000000,60,8.00,67235.61000000,67229.10000000,'lost',2,'2026-02-19 07:28:22',NULL,'2026-02-19 07:29:22');
/*!40000 ALTER TABLE `binary_orders` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `chat_remarks`
--
DROP TABLE IF EXISTS `chat_remarks`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `chat_remarks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT 0,
`ip_address` varchar(45) DEFAULT NULL,
`remark` text DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`ip_address`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `chat_remarks`
--
LOCK TABLES `chat_remarks` WRITE;
/*!40000 ALTER TABLE `chat_remarks` DISABLE KEYS */;
INSERT INTO `chat_remarks` VALUES
(1,2,'::1','测试','2026-02-19 02:39:36');
/*!40000 ALTER TABLE `chat_remarks` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `chat_visitors`
--
DROP TABLE IF EXISTS `chat_visitors`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `chat_visitors` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT 0,
`ip_address` varchar(45) DEFAULT NULL,
`last_ping` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user_time` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`ip_address`)
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `chat_visitors`
--
LOCK TABLES `chat_visitors` WRITE;
/*!40000 ALTER TABLE `chat_visitors` DISABLE KEYS */;
INSERT INTO `chat_visitors` VALUES
(1,2,'45.201.166.50','2026-02-20 06:59:44','14:59:55');
/*!40000 ALTER TABLE `chat_visitors` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `contract_orders`
--
DROP TABLE IF EXISTS `contract_orders`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `contract_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(20) NOT NULL,
`type` enum('limit','market') DEFAULT 'market',
`direction` varchar(10) DEFAULT NULL,
`leverage` int(11) DEFAULT 1,
`amount` decimal(20,8) NOT NULL,
`entry_price` decimal(20,8) DEFAULT NULL,
`close_price` decimal(20,8) DEFAULT NULL,
`status` enum('open','closed','cancelled') DEFAULT 'open',
`profit` decimal(20,8) DEFAULT 0.00000000,
`control_status` tinyint(4) DEFAULT 0 COMMENT '0: normal, 1: force win, 2: force loss',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `contract_orders`
--
LOCK TABLES `contract_orders` WRITE;
/*!40000 ALTER TABLE `contract_orders` DISABLE KEYS */;
/*!40000 ALTER TABLE `contract_orders` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `exchange_records`
--
DROP TABLE IF EXISTS `exchange_records`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `exchange_records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`from_symbol` varchar(10) NOT NULL,
`to_symbol` varchar(10) NOT NULL,
`from_amount` decimal(20,8) NOT NULL,
`to_amount` decimal(20,8) NOT NULL,
`rate` decimal(20,8) NOT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `exchange_records`
--
LOCK TABLES `exchange_records` WRITE;
/*!40000 ALTER TABLE `exchange_records` DISABLE KEYS */;
INSERT INTO `exchange_records` VALUES
(1,2,'USDT','ETH',10000.00000000,5.14204911,0.00051420,'2026-02-20 05:26:38',NULL),
(2,2,'USDT','ETH',5000.00000000,2.55090327,0.00051018,'2026-02-20 05:34:45',NULL),
(3,2,'ETH','USDT',4.00000000,7853.84000000,1963.46000000,'2026-02-20 05:35:13',NULL),
(4,2,'USDT','ETH',872.00000000,0.44480718,0.00051010,'2026-02-20 05:37:53',NULL),
(5,2,'USDT','ETH',7000.00000000,3.57699481,0.00051100,'2026-02-20 05:41:14',NULL);
/*!40000 ALTER TABLE `exchange_records` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `finance_requests`
--
DROP TABLE IF EXISTS `finance_requests`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `finance_requests` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`type` enum('recharge','withdrawal') NOT NULL,
`amount` decimal(20,8) NOT NULL,
`symbol` varchar(10) DEFAULT 'USDT',
`status` enum('pending','approved','rejected') DEFAULT 'pending',
`payment_method` varchar(50) DEFAULT NULL,
`payment_details` text DEFAULT NULL,
`rejection_reason` text DEFAULT NULL,
`tx_hash` varchar(255) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`fiat_amount` decimal(20,2) DEFAULT NULL,
`fiat_currency` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `finance_requests`
--
LOCK TABLES `finance_requests` WRITE;
/*!40000 ALTER TABLE `finance_requests` DISABLE KEYS */;
INSERT INTO `finance_requests` VALUES
(1,2,'recharge',209.64000000,'USDT','approved','Fiat (MYR)',NULL,NULL,'','2026-02-18 04:45:54',NULL,'2026-02-18 04:46:29',NULL,NULL),
(2,2,'recharge',10.00000000,'USDT','approved','Fiat (MYR)',NULL,NULL,'','2026-02-18 06:15:15',NULL,'2026-02-18 06:16:15',NULL,NULL),
(3,2,'recharge',10.00000000,'USDT','approved','Fiat (MYR)',NULL,NULL,'','2026-02-18 06:33:05',NULL,'2026-02-18 06:33:17',NULL,NULL),
(4,2,'recharge',10.00000000,'USDT','approved','Fiat (MYR: 50000)',NULL,NULL,'','2026-02-18 06:37:57',NULL,'2026-02-18 06:38:22',NULL,NULL),
(5,2,'recharge',209.64000000,'USDT','approved','Fiat (MYR)',NULL,NULL,'','2026-02-18 06:54:02',NULL,'2026-02-18 06:54:16',1000.00,'MYR'),
(6,2,'withdrawal',9249.28000000,'USDT','approved',NULL,'Fiat (MYR)',NULL,NULL,'2026-02-18 06:54:44',NULL,'2026-02-18 06:54:58',44119.07,'MYR'),
(7,2,'recharge',10000.00000000,'USDT','approved','Fiat (USD)',NULL,NULL,'','2026-02-18 06:56:22',NULL,'2026-02-18 06:56:45',10000.00,'USD'),
(8,2,'recharge',100.00000000,'USDT','approved','Fiat (USD)',NULL,NULL,'','2026-02-18 07:09:10',NULL,'2026-02-18 07:10:11',100.00,'USD'),
(9,2,'withdrawal',1000.00000000,'USDT','approved',NULL,'Fiat (USD)',NULL,NULL,'2026-02-18 08:13:47',NULL,'2026-02-18 08:14:10',1000.00,'USD'),
(10,2,'recharge',100.00000000,'USDT','approved','Fiat (USD)',NULL,NULL,'','2026-02-18 09:05:05',NULL,'2026-02-18 09:05:52',100.00,'USD'),
(11,2,'withdrawal',100.00000000,'USDT','approved',NULL,'Fiat (USD)',NULL,NULL,'2026-02-18 09:06:13',NULL,'2026-02-18 09:06:48',100.00,'USD'),
(12,2,'recharge',209.64000000,'USDT','approved','Fiat (MYR)',NULL,NULL,'','2026-02-18 09:26:51',NULL,'2026-02-18 09:27:12',1000.00,'MYR'),
(13,2,'withdrawal',700.00000000,'USDT','approved',NULL,'Fiat (USD)',NULL,NULL,'2026-02-18 09:27:38',NULL,'2026-02-18 09:27:52',700.00,'USD'),
(14,2,'recharge',746.27000000,'USDT','approved','Fiat (SGD)',NULL,NULL,'','2026-02-18 11:17:06',NULL,'2026-02-18 11:18:57',1000.00,'SGD'),
(15,2,'withdrawal',1000.00000000,'USDT','approved',NULL,'Fiat (MYR)',NULL,NULL,'2026-02-18 11:18:24',NULL,'2026-02-18 11:19:04',4770.00,'MYR'),
(16,2,'recharge',1000.00000000,'USDT','approved','TRC20',NULL,NULL,'','2026-02-18 11:21:13',NULL,'2026-02-18 11:21:33',NULL,NULL),
(17,2,'recharge',746.26865672,'USDT','approved','Fiat (SGD)',NULL,NULL,'','2026-02-18 11:41:32',NULL,'2026-02-18 11:41:46',1000.00,'SGD'),
(18,2,'recharge',12820.51282051,'USDT','approved','法币充值 (MYR)',NULL,NULL,'','2026-02-18 15:19:59',NULL,'2026-02-18 15:20:45',50000.00,'MYR'),
(19,2,'withdrawal',4000.00000000,'USDT','approved',NULL,'法币提现 (USD)',NULL,NULL,'2026-02-19 02:14:37',NULL,'2026-02-19 02:15:22',4000.00,'USD'),
(20,2,'recharge',1447.17800289,'USDT','approved','法币充值 (CNY)',NULL,NULL,'','2026-02-19 02:17:27',NULL,'2026-02-19 02:17:53',10000.00,'CNY'),
(21,2,'withdrawal',857.00000000,'USDT','approved',NULL,'法币提现 (JPY)',NULL,NULL,'2026-02-19 02:22:07',NULL,'2026-02-19 02:45:31',132337.94,'JPY'),
(22,2,'recharge',3177.62948840,'USDT','approved','法币充值 (TWD)',NULL,NULL,'','2026-02-19 02:22:40',NULL,'2026-02-19 02:42:46',100000.00,'TWD'),
(23,2,'withdrawal',21000.00000000,'USDT','approved',NULL,'法币提现 (USD)',NULL,NULL,'2026-02-19 02:42:12',NULL,'2026-02-19 02:45:37',21000.00,'USD'),
(24,2,'recharge',20000.00000000,'USDT','approved','法币充值 (USD)',NULL,NULL,'','2026-02-19 07:07:28',NULL,'2026-02-19 07:07:42',20000.00,'USD');
/*!40000 ALTER TABLE `finance_requests` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `messages`
--
DROP TABLE IF EXISTS `messages`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`admin_id` int(11) DEFAULT NULL,
`sender` enum('user','admin') DEFAULT NULL,
`message` text DEFAULT NULL,
`ip_address` varchar(45) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `messages`
--
LOCK TABLES `messages` WRITE;
/*!40000 ALTER TABLE `messages` DISABLE KEYS */;
INSERT INTO `messages` VALUES
(1,1,NULL,'user','1','::1','2026-02-16 03:27:13'),
(2,1,1,'admin','1','::1','2026-02-16 03:27:24'),
(3,1,NULL,'user','1','::1','2026-02-16 05:05:24'),
(4,1,1,'admin','你好','::1','2026-02-16 05:05:50'),
(5,1,NULL,'user','[Recharge Request]Fiat Amount: 1000 CNYEstimated USDT: 139.08 USDTPlease provide payment details.','::1','2026-02-16 06:43:24'),
(6,1,NULL,'user','1','::1','2026-02-18 03:03:47'),
(7,1,1,'admin','222','::1','2026-02-18 03:04:14'),
(8,2,NULL,'user','【充值】类型法币充值金额1000 MYR预计到账 USDT209.64 USDT','::1','2026-02-18 03:21:37'),
(9,2,NULL,'user','【充值】类型法币充值金额1000 MYR预计到账 USDT209.64 USDT','::1','2026-02-18 04:45:54'),
(10,2,2,'admin','11','::1','2026-02-18 09:00:56'),
(11,2,NULL,'user','你好手上','::1','2026-02-18 09:04:32'),
(12,2,1,'admin','你好','::1','2026-02-18 09:04:43'),
(13,2,NULL,'user','[RECHARGE REQUEST]------------------Type: Fiat RechargeAmount: 100 USDRate: 1 USDT = 1 USDEst. USDT: 100.00 USDTStatus: Pending Approval------------------Please confirm my deposit.','::1','2026-02-18 09:05:05'),
(14,2,NULL,'user','[WITHDRAWAL REQUEST]------------------Type: Fiat WithdrawalAmount: 100.00 USDTRate: 1 USDT = 1 USDTo Receive: 100.00 USD------------------Please process my fiat withdrawal.','::1','2026-02-18 09:06:13'),
(15,2,1,'admin','2222','::1','2026-02-18 09:21:27'),
(16,2,NULL,'user','2222','::1','2026-02-18 09:21:34'),
(17,2,NULL,'user','1','::1','2026-02-18 09:21:37'),
(18,2,1,'admin','123','::1','2026-02-18 09:25:25'),
(19,2,NULL,'user','321','::1','2026-02-18 09:25:32'),
(20,2,NULL,'user','recharge_msg_fiat','::1','2026-02-18 09:26:52'),
(21,2,NULL,'user','withdraw_msg_fiat','::1','2026-02-18 09:27:38'),
(22,2,NULL,'user','用户ID05617613 申请充值金额1000 SGD=1.34USDT','::1','2026-02-18 11:17:06'),
(23,2,1,'admin','1','::1','2026-02-18 11:17:41'),
(24,2,NULL,'user','用户ID05617613 申请提现金额1000.00 MYR=4.77USDT','::1','2026-02-18 11:18:24'),
(25,2,NULL,'user','用户ID05617613 申请充值金额1000 USDT (TRC20)','::1','2026-02-18 11:21:13'),
(26,2,NULL,'user','用户ID05617613 申请充值金额1000 SGD=746.2687USDT','::1','2026-02-18 11:41:32'),
(28,2,NULL,'user','用户ID05617613 申请充值金额50000 MYR=12820.5128泰达币','::1','2026-02-18 15:20:00'),
(29,2,NULL,'user','用户ID05617613 申请提现金额4000.00 USDT=4000.00 USD','::1','2026-02-19 02:14:38'),
(30,2,NULL,'user','用户ID05617613 申请充值金额10000 CNY=1447.1780 USDT','::1','2026-02-19 02:17:28'),
(31,2,NULL,'user','用户ID05617613 申请提现金额857.00 USDT=132337.94 JPY','::1','2026-02-19 02:22:08'),
(32,2,NULL,'user','用户ID05617613 申请充值金额100000 TWD=3177.6295 USDT','::1','2026-02-19 02:22:41'),
(33,2,NULL,'user','2222','45.201.166.50','2026-02-19 02:40:51'),
(34,2,NULL,'user','用户ID05617613 申请提现金额21000.00 USDT=21000.00 USD','45.201.166.50','2026-02-19 02:42:12'),
(35,2,NULL,'user','用户ID05617613 申请充值金额20000 USD=20000.0000 USDT','45.201.166.50','2026-02-19 07:07:28'),
(36,2,NULL,'user','1233344','45.201.166.50','2026-02-19 11:06:33'),
(37,2,NULL,'user','对的得到','45.201.166.50','2026-02-19 11:07:41'),
(38,2,1,'admin','如发了','45.201.166.50','2026-02-19 11:07:48'),
(39,2,NULL,'user','你好手上','45.201.166.50','2026-02-19 11:18:15'),
(40,2,1,'admin','是是是','45.201.166.50','2026-02-19 11:18:27'),
(41,2,NULL,'user','00090','45.201.166.50','2026-02-19 11:32:53'),
(42,2,1,'admin','222','45.201.166.50','2026-02-19 11:33:12'),
(43,2,NULL,'user','你好吗','45.201.166.50','2026-02-20 05:57:32'),
(44,2,1,'admin','111','0','2026-02-20 05:58:24'),
(45,2,NULL,'user','百年建党撒活动','45.201.166.50','2026-02-20 05:58:34'),
(46,2,NULL,'user','在吗','45.201.166.50','2026-02-20 06:09:36'),
(47,2,1,'admin','在的','0','2026-02-20 06:09:47'),
(48,2,NULL,'user','少时诵诗书','45.201.166.50','2026-02-20 06:10:30'),
(49,2,NULL,'user','321','45.201.166.50','2026-02-20 06:15:24'),
(50,2,NULL,'user','你好吗','45.201.166.50','2026-02-20 06:27:35'),
(52,2,NULL,'user','5156156563','45.201.166.50','2026-02-20 06:28:01'),
(55,2,NULL,'user','少时诵诗书','45.201.166.50','2026-02-20 06:36:55'),
(57,2,NULL,'user','我在的','45.201.166.50','2026-02-20 06:43:39');
/*!40000 ALTER TABLE `messages` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `price_controls`
--
DROP TABLE IF EXISTS `price_controls`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `price_controls` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`symbol` varchar(20) NOT NULL,
`target_price` decimal(20,8) NOT NULL,
`execution_time` timestamp NOT NULL,
`duration` int(11) DEFAULT 60 COMMENT 'seconds',
`created_at` timestamp NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `price_controls`
--
LOCK TABLES `price_controls` WRITE;
/*!40000 ALTER TABLE `price_controls` DISABLE KEYS */;
/*!40000 ALTER TABLE `price_controls` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `spot_orders`
--
DROP TABLE IF EXISTS `spot_orders`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `spot_orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(20) NOT NULL,
`side` enum('buy','sell') NOT NULL,
`price` decimal(20,8) DEFAULT NULL,
`amount` decimal(20,8) NOT NULL,
`filled` decimal(20,8) DEFAULT 0.00000000,
`status` enum('pending','filled','cancelled') DEFAULT 'pending',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `spot_orders`
--
LOCK TABLES `spot_orders` WRITE;
/*!40000 ALTER TABLE `spot_orders` DISABLE KEYS */;
/*!40000 ALTER TABLE `spot_orders` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `staking_records`
--
DROP TABLE IF EXISTS `staking_records`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `staking_records` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`plan_name` varchar(100) NOT NULL,
`amount` decimal(20,8) NOT NULL,
`symbol` varchar(10) DEFAULT 'USDT',
`daily_profit` decimal(5,2) NOT NULL,
`period` int(11) NOT NULL COMMENT 'days',
`status` enum('running','ended') DEFAULT 'running',
`start_date` date NOT NULL,
`end_date` date NOT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `staking_records`
--
LOCK TABLES `staking_records` WRITE;
/*!40000 ALTER TABLE `staking_records` DISABLE KEYS */;
INSERT INTO `staking_records` VALUES
(1,2,'ETH矿池',3.00000000,'ETH',0.02,0,'running','2026-02-20','2099-12-31','2026-02-20 05:29:16',NULL);
/*!40000 ALTER TABLE `staking_records` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `system_settings`
--
DROP TABLE IF EXISTS `system_settings`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `system_settings` (
`setting_key` varchar(50) NOT NULL,
`setting_value` text DEFAULT NULL,
PRIMARY KEY (`setting_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `system_settings`
--
LOCK TABLES `system_settings` WRITE;
/*!40000 ALTER TABLE `system_settings` DISABLE KEYS */;
INSERT INTO `system_settings` VALUES
('android_download_url','/downloads/byro.apk'),
('apk_download_url','/downloads/byro.apk'),
('email_verification_enabled','0'),
('ios_download_url','/downloads/byro.apk'),
('mail_from_email',''),
('mail_from_name','Byro Exchange'),
('service_link',''),
('site_favicon','/assets/images/favicon_byro_final.png'),
('site_logo','/assets/images/logo_byro_final.png'),
('site_name','BYRO'),
('smtp_host',''),
('smtp_pass',''),
('smtp_port','587'),
('smtp_secure','tls'),
('smtp_user',''),
('usdt_bep20_address','0x742d35Cc6634C0532925a3b844Bc454e4438f44e'),
('usdt_erc20_address','0x742d35Cc6634C0532925a3b844Bc454e4438f44e'),
('usdt_protocol','TRC20'),
('usdt_recharge_address',''),
('usdt_trc20_address','TYv9V5J1P1eEwz7y3WqJg9M2yv7f7xXv3x');
/*!40000 ALTER TABLE `system_settings` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `transactions`
--
DROP TABLE IF EXISTS `transactions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `transactions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`type` varchar(20) NOT NULL,
`amount` decimal(20,8) NOT NULL,
`symbol` varchar(10) NOT NULL,
`status` varchar(20) DEFAULT 'completed',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`ip_address` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `transactions`
--
LOCK TABLES `transactions` WRITE;
/*!40000 ALTER TABLE `transactions` DISABLE KEYS */;
INSERT INTO `transactions` VALUES
(1,1,'deposit',5000.00000000,'USDT','completed','2026-02-15 15:40:31',NULL),
(2,1,'deposit',1000.00000000,'USDT','completed','2026-02-15 15:45:53',NULL),
(3,2,'recharge',209.64000000,'USDT','completed','2026-02-18 04:46:29',NULL),
(4,2,'recharge',10.00000000,'USDT','completed','2026-02-18 06:16:15',NULL),
(5,2,'recharge',10.00000000,'USDT','completed','2026-02-18 06:33:17',NULL),
(6,2,'recharge',10.00000000,'USDT','completed','2026-02-18 06:38:22',NULL),
(7,2,'recharge',209.64000000,'USDT','completed','2026-02-18 06:54:16',NULL),
(8,2,'withdrawal',9249.28000000,'USDT','pending','2026-02-18 06:54:44',NULL),
(9,2,'recharge',10000.00000000,'USDT','completed','2026-02-18 06:56:45',NULL),
(10,2,'recharge',100.00000000,'USDT','completed','2026-02-18 07:10:11',NULL),
(11,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:00:59',NULL),
(12,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:00:59',NULL),
(13,2,'binary_win',1080.00000000,'USDT','completed','2026-02-18 08:00:59',NULL),
(14,2,'binary_win',540.00000000,'USDT','completed','2026-02-18 08:00:59',NULL),
(15,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:00:59',NULL),
(16,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:00:59',NULL),
(17,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:01:00',NULL),
(18,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:01:00',NULL),
(19,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:01:00',NULL),
(20,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:01:00',NULL),
(21,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:01:00',NULL),
(22,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:03:35',NULL),
(23,2,'withdrawal',1000.00000000,'USDT','completed','2026-02-18 08:13:47',NULL),
(24,2,'binary_win',108.00000000,'USDT','completed','2026-02-18 08:38:40',NULL),
(25,2,'recharge',100.00000000,'USDT','completed','2026-02-18 09:05:52',NULL),
(26,2,'withdrawal',100.00000000,'USDT','completed','2026-02-18 09:06:13',NULL),
(27,2,'recharge',209.64000000,'USDT','completed','2026-02-18 09:27:12',NULL),
(28,2,'withdrawal',700.00000000,'USDT','completed','2026-02-18 09:27:38',NULL),
(29,2,'withdrawal',1000.00000000,'USDT','completed','2026-02-18 11:18:24',NULL),
(30,2,'recharge',746.27000000,'USDT','completed','2026-02-18 11:18:57',NULL),
(31,2,'recharge',1000.00000000,'USDT','completed','2026-02-18 11:21:33',NULL),
(32,2,'recharge',746.26865672,'USDT','completed','2026-02-18 11:41:46',NULL),
(33,2,'binary_win',1080.00000000,'USDT','completed','2026-02-18 15:17:14',NULL),
(34,2,'recharge',12820.51282051,'USDT','completed','2026-02-18 15:20:45',NULL),
(35,2,'withdrawal',4000.00000000,'USDT','completed','2026-02-19 02:14:37',NULL),
(36,2,'recharge',1447.17800289,'USDT','completed','2026-02-19 02:17:53',NULL),
(37,2,'withdrawal',857.00000000,'USDT','completed','2026-02-19 02:22:07',NULL),
(38,2,'withdrawal',21000.00000000,'USDT','completed','2026-02-19 02:42:12',NULL),
(39,2,'recharge',3177.62948840,'USDT','completed','2026-02-19 02:42:46',NULL),
(40,2,'recharge',20000.00000000,'USDT','completed','2026-02-19 07:07:42',NULL),
(41,2,'binary_win',25760.00000000,'USDT','completed','2026-02-19 07:24:01',NULL),
(42,2,'binary_win',1080.00000000,'USDT','completed','2026-02-19 07:27:41',NULL),
(43,2,'binary_loss',1000.00000000,'USDT','completed','2026-02-19 07:29:22',NULL),
(44,2,'swap',10000.00000000,'USDT','completed','2026-02-20 05:26:38',NULL),
(45,2,'mining',3.00000000,'ETH','completed','2026-02-20 05:29:16',NULL),
(46,2,'swap',5000.00000000,'USDT','completed','2026-02-20 05:34:45',NULL),
(47,2,'swap',4.00000000,'ETH','completed','2026-02-20 05:35:13',NULL),
(48,2,'swap',872.00000000,'USDT','completed','2026-02-20 05:37:53',NULL),
(49,2,'swap',7000.00000000,'USDT','completed','2026-02-20 05:41:14',NULL);
/*!40000 ALTER TABLE `transactions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `user_balances`
--
DROP TABLE IF EXISTS `user_balances`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_balances` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`symbol` varchar(10) NOT NULL,
`available` decimal(20,8) DEFAULT 0.00000000,
`frozen` decimal(20,8) DEFAULT 0.00000000,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`symbol`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `user_balances`
--
LOCK TABLES `user_balances` WRITE;
/*!40000 ALTER TABLE `user_balances` DISABLE KEYS */;
INSERT INTO `user_balances` VALUES
(1,1,'USDT',6000.00000000,0.00000000),
(6,2,'USDT',10000.33896852,0.00000000),
(7,2,'ETH',4.71475437,3.00000000);
/*!40000 ALTER TABLE `user_balances` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`password_hash` varchar(255) NOT NULL,
`created_at` timestamp NULL DEFAULT current_timestamp(),
`uid` varchar(20) DEFAULT NULL,
`credit_score` int(11) DEFAULT 80,
`real_name_status` int(11) DEFAULT 0,
`role` varchar(20) DEFAULT 'user',
`vip_level` int(11) DEFAULT 0,
`total_recharge` decimal(16,4) DEFAULT 0.0000,
`transaction_password` varchar(255) DEFAULT NULL,
`kyc_name` varchar(100) DEFAULT NULL,
`kyc_id_number` varchar(50) DEFAULT NULL,
`kyc_photo_front` varchar(255) DEFAULT NULL,
`kyc_photo_back` varchar(255) DEFAULT NULL,
`kyc_photo_handheld` varchar(255) DEFAULT NULL,
`kyc_status` int(11) DEFAULT 0 COMMENT '0: Unverified, 1: Pending, 2: Verified, 3: Rejected',
`registration_ip` varchar(45) DEFAULT NULL,
`status` enum('normal','frozen') DEFAULT 'normal',
`win_loss_control` tinyint(4) DEFAULT 0 COMMENT '0: normal, 1: win, 2: loss',
`remark` text DEFAULT NULL,
`kyc_rejection_reason` text DEFAULT NULL,
`agent_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `uid` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `users`
--
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES
(2,'ahao8988998','ahao8988@gmail.com','$2y$10$tdT4vIgddq1kh2isoBRIPe4goiZ3X1cbf2l6vtButmyZx71xP527q','2026-02-18 02:56:51','05617613',80,0,'user',0,0.0000,NULL,'张世豪','123456789','uploads/kyc/2_front_1771391536.jpg','uploads/kyc/2_back_1771391536.jpg','uploads/kyc/2_handheld_1771391536.jpg',2,NULL,'normal',1,'',NULL,NULL);
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2026-02-20 7:10:01

View File

@ -189,9 +189,9 @@ $service_link = getSetting('service_link');
<div class="bg-white rounded-circle" style="width: 10px; height: 10px;"></div>
<span class="fw-bold"><?= __('online_support') ?></span>
</div>
<?php if (isset($_SESSION['uid'])): ?>
<?php if (isset($_SESSION['username'])): ?>
<div style="font-size: 10px; opacity: 0.8;">
IP: <?= getRealIP() ?>
<?= htmlspecialchars($_SESSION['username']) ?>
</div>
<?php endif; ?>
</div>
@ -238,7 +238,7 @@ csFileInput.addEventListener('change', async () => {
});
const data = await resp.json();
if (data.success) {
// Success
pollMessages();
} else {
alert(data.error || '<?= __("send_failed") ?>');
}
@ -311,6 +311,8 @@ function appendMessage(sender, text, time = null) {
// Polling for new messages
let lastMsgId = 0;
let lastPingTime = 0;
let lastChatHtml = '';
async function pollMessages() {
if (csBox.classList.contains('d-none')) return;
@ -325,18 +327,33 @@ async function pollMessages() {
try {
const resp = await fetch('/api/chat.php?action=get_messages');
const data = await resp.json();
if (data && data.length > 0) {
let hasNew = false;
if (data) {
let html = '<div class="text-center text-muted small mb-3"><?= __("welcome_support") ?></div>';
data.forEach(m => {
if (parseInt(m.id) > lastMsgId) {
// Check if this is an image upload temp message and remove it if needed
// Actually, simple append is fine.
appendMessage(m.sender, m.message, m.created_at);
lastMsgId = parseInt(m.id);
hasNew = true;
}
const sender = m.sender;
const text = m.message;
const time = m.created_at;
const isImage = text.indexOf('<img') !== -1;
let dateObj = new Date(time.replace(/-/g, "/"));
const timeStr = dateObj.toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit', second: '2-digit'});
html += `
<div class="mb-3 d-flex flex-column ${sender === 'user' ? 'align-items-end' : 'align-items-start'}">
<div class="p-2 px-3 rounded-4 small ${sender === 'user' ? 'bg-primary text-white' : 'bg-dark text-white border border-secondary'}" style="max-width: 80%; color: #ffffff !important; word-break: break-all; position: relative; padding-bottom: 20px !important; ${isImage ? 'padding: 5px !important;' : ''}">
${text}
<div style="font-size: 9px; opacity: 0.6; position: absolute; bottom: 4px; ${sender === 'user' ? 'right: 10px;' : 'left: 10px;'} ${isImage ? 'background: rgba(0,0,0,0.4); padding: 0 4px; border-radius: 4px;' : ''}">${timeStr}</div>
</div>
</div>
`;
if (parseInt(m.id) > lastMsgId) lastMsgId = parseInt(m.id);
});
if (hasNew) scrollToBottom();
if (csMessages.innerHTML !== html) {
const isAtBottom = csMessages.scrollTop + csMessages.clientHeight >= csMessages.scrollHeight - 50;
csMessages.innerHTML = html;
if (isAtBottom) scrollToBottom();
}
}
} catch (err) {}
}

View File

@ -3,7 +3,7 @@ session_start();
$lang = $_SESSION['lang'] ?? 'en';
if (isset($_GET['lang'])) {
$lang = $_GET['lang'] === 'zh' ? 'zh' : 'en';
$lang = $_GET['lang'] === 'en' ? 'en' : 'zh';
$_SESSION['lang'] = $lang;
}