Autosave: 20260216-073240
This commit is contained in:
parent
9f605f214e
commit
e5387b40a5
@ -7,7 +7,7 @@
|
||||
--term-primary: #0062ff;
|
||||
--term-success: #26a69a;
|
||||
--term-danger: #ef5350;
|
||||
--header-height: 60px;
|
||||
--header-height: 70px;
|
||||
--sidebar-width: 280px;
|
||||
--orderbook-width: 300px;
|
||||
}
|
||||
@ -364,65 +364,216 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Binary Order Panel */
|
||||
/* Binary Order Panel Improvements */
|
||||
.cycle-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 1px;
|
||||
background: var(--term-border);
|
||||
border: 1px solid var(--term-border);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
gap: 8px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.cycle-btn {
|
||||
background: var(--term-bg);
|
||||
border: none;
|
||||
background: #1e2329;
|
||||
border: 1px solid var(--term-border);
|
||||
color: var(--term-muted);
|
||||
padding: 12px 5px;
|
||||
padding: 10px 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s;
|
||||
font-weight: 700;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.cycle-btn:hover {
|
||||
background: rgba(255,255,255,0.05);
|
||||
color: var(--term-text);
|
||||
background: #2b3139;
|
||||
border-color: var(--term-primary);
|
||||
color: #fff;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.cycle-btn.active {
|
||||
background: var(--term-primary);
|
||||
background: linear-gradient(135deg, var(--term-primary), #004ecc);
|
||||
border-color: var(--term-primary);
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 15px rgba(0, 98, 255, 0.3);
|
||||
}
|
||||
|
||||
.cycle-btn .cycle-time { font-size: 13px; }
|
||||
.cycle-btn .cycle-profit { font-size: 10px; opacity: 0.8; }
|
||||
|
||||
.amount-input-wrapper input {
|
||||
height: 44px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
background: #0b0e11 !important;
|
||||
border: 1px solid var(--term-border) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.amount-input-wrapper input:focus {
|
||||
border-color: var(--term-primary) !important;
|
||||
box-shadow: 0 0 0 1px var(--term-primary) !important;
|
||||
}
|
||||
|
||||
.binary-order-panel .btn-buy-sell {
|
||||
height: 60px; /* Reduced height as requested */
|
||||
border-radius: 12px;
|
||||
transition: all 0.2s;
|
||||
border: none;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.binary-order-panel .btn-buy-sell:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.btn-success.btn-buy-sell {
|
||||
background: linear-gradient(135deg, #26a69a, #1b8076);
|
||||
box-shadow: 0 4px 12px rgba(38, 166, 154, 0.2);
|
||||
}
|
||||
|
||||
.btn-danger.btn-buy-sell {
|
||||
background: linear-gradient(135deg, #ef5350, #c62828);
|
||||
box-shadow: 0 4px 12px rgba(239, 83, 80, 0.2);
|
||||
}
|
||||
|
||||
/* Ensure history is visible */
|
||||
.terminal-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.kline-container {
|
||||
flex: 1;
|
||||
min-height: 300px; /* Allow it to shrink slightly to show more history */
|
||||
}
|
||||
|
||||
.order-history {
|
||||
height: 300px; /* Fixed height for scrollable area */
|
||||
border-top: 1px solid var(--term-border);
|
||||
background: var(--term-surface);
|
||||
}
|
||||
|
||||
.trading-panels {
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid var(--term-border);
|
||||
}
|
||||
|
||||
/* Enhanced Balance and Profit visibility */
|
||||
.balance-highlight {
|
||||
color: #0062ff !important;
|
||||
text-shadow: 0 0 10px rgba(0, 98, 255, 0.3);
|
||||
}
|
||||
|
||||
.profit-highlight {
|
||||
color: #26a69a !important;
|
||||
font-size: 1.1rem;
|
||||
text-shadow: 0 0 10px rgba(38, 166, 154, 0.3);
|
||||
}
|
||||
|
||||
/* Order Countdown Popup */
|
||||
.order-popup-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
backdrop-filter: blur(5px);
|
||||
z-index: 9999;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.order-popup {
|
||||
background: #1e2329;
|
||||
width: 360px;
|
||||
border-radius: 20px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.order-popup h5 {
|
||||
color: #848e9c;
|
||||
font-size: 16px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.countdown-circle {
|
||||
position: relative;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin: 0 auto 30px;
|
||||
}
|
||||
|
||||
.countdown-circle svg {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.countdown-circle circle {
|
||||
fill: none;
|
||||
stroke-width: 8;
|
||||
}
|
||||
|
||||
.countdown-circle .bg {
|
||||
stroke: #2b3139;
|
||||
}
|
||||
|
||||
.countdown-circle .progress {
|
||||
stroke: #26a69a;
|
||||
stroke-linecap: round;
|
||||
transition: stroke-dashoffset 1s linear;
|
||||
}
|
||||
|
||||
.countdown-circle .time-text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.amount-input-wrapper input {
|
||||
height: 50px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--term-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.quick-amounts .btn {
|
||||
font-weight: 600;
|
||||
background: #2b3139;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.quick-amounts .btn:hover {
|
||||
background: #3b424c;
|
||||
}
|
||||
|
||||
.binary-order-panel {
|
||||
background: var(--term-surface);
|
||||
.popup-details {
|
||||
background: rgba(255,255,255,0.03);
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.popup-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.popup-row .label { color: #848e9c; }
|
||||
.popup-row .value { color: #eaecef; font-weight: 600; }
|
||||
|
||||
.popup-footer {
|
||||
font-size: 11px;
|
||||
color: #5e6673;
|
||||
}
|
||||
|
||||
.terminal-main {
|
||||
height: calc(100vh - var(--header-height));
|
||||
}
|
||||
|
||||
|
||||
BIN
assets/pasted-20260216-060142-d6502859.png
Normal file
BIN
assets/pasted-20260216-060142-d6502859.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
assets/pasted-20260216-072002-eb8999c7.png
Normal file
BIN
assets/pasted-20260216-072002-eb8999c7.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
@ -33,8 +33,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
} else {
|
||||
try {
|
||||
$hash = password_hash($password, PASSWORD_DEFAULT);
|
||||
$uid = '618120' . mt_rand(100000, 999999);
|
||||
$stmt = db()->prepare("INSERT INTO users (username, email, password_hash, uid, credit_score) VALUES (?, ?, ?, ?, ?)");
|
||||
$uid = str_pad(mt_rand(0, 99999999), 8, '0', STR_PAD_LEFT);
|
||||
$stmt = db()->prepare("INSERT INTO users (username, email, password_hash, uid, credit_score, total_recharge) VALUES (?, ?, ?, ?, ?, 0)");
|
||||
|
||||
$username = strpos($account, '@') === false ? $account : explode('@', $account)[0];
|
||||
$email = strpos($account, '@') !== false ? $account : $account . '@byro.io';
|
||||
|
||||
17
db/migrations/003_update_users_for_profile.sql
Normal file
17
db/migrations/003_update_users_for_profile.sql
Normal file
@ -0,0 +1,17 @@
|
||||
-- Add missing fields for Profile, KYC and Security
|
||||
ALTER TABLE users
|
||||
ADD COLUMN total_recharge DECIMAL(16,4) DEFAULT 0,
|
||||
ADD COLUMN transaction_password VARCHAR(255) DEFAULT NULL,
|
||||
ADD COLUMN kyc_name VARCHAR(100) DEFAULT NULL,
|
||||
ADD COLUMN kyc_id_number VARCHAR(50) DEFAULT NULL,
|
||||
ADD COLUMN kyc_photo_front VARCHAR(255) DEFAULT NULL,
|
||||
ADD COLUMN kyc_photo_back VARCHAR(255) DEFAULT NULL,
|
||||
ADD COLUMN kyc_photo_handheld VARCHAR(255) DEFAULT NULL,
|
||||
ADD COLUMN kyc_status INT DEFAULT 0 COMMENT '0: Unverified, 1: Pending, 2: Verified, 3: Rejected';
|
||||
|
||||
-- Update credit_score default
|
||||
ALTER TABLE users MODIFY COLUMN credit_score INT DEFAULT 80;
|
||||
|
||||
-- Ensure existing users have a credit score and UID if missing
|
||||
UPDATE users SET credit_score = 80 WHERE credit_score IS NULL;
|
||||
UPDATE users SET uid = LPAD(FLOOR(RAND() * 100000000), 8, '0') WHERE uid IS NULL OR uid = '';
|
||||
@ -72,7 +72,10 @@
|
||||
<!-- Customer Service Widget -->
|
||||
<div id="cs-widget" style="position: fixed; bottom: 30px; right: 30px; z-index: 9999;">
|
||||
<button class="btn btn-primary rounded-circle shadow-lg p-0 d-flex align-items-center justify-content-center transition-all" id="cs-toggle" style="width: 70px; height: 70px; border: none; background: linear-gradient(135deg, #00c6ff, #0072ff); box-shadow: 0 10px 20px rgba(0, 114, 255, 0.4);">
|
||||
<img src="https://img.icons8.com/fluency/96/service.png" alt="Support" style="width: 45px; height: 45px;">
|
||||
<div class="position-relative d-flex align-items-center justify-content-center">
|
||||
<i class="bi bi-person-fill text-white position-absolute" style="font-size: 1.2rem; margin-top: 4px;"></i>
|
||||
<i class="bi bi-headset text-white" style="font-size: 2.4rem;"></i>
|
||||
</div>
|
||||
</button>
|
||||
<div class="pulse-ring"></div>
|
||||
</div>
|
||||
|
||||
@ -322,8 +322,11 @@ function getSetting($key, $default = null) {
|
||||
<div class="user-stats">
|
||||
<div class="stat-item">
|
||||
<span class="stat-label"><?= __('real_name') ?? 'Real-name' ?></span>
|
||||
<span class="stat-value <?= ($user['real_name_status'] ?? 0) ? 'success' : 'text-warning' ?>">
|
||||
<?= ($user['real_name_status'] ?? 0) ? (__('verified') ?? 'Verified') : (__('unverified') ?? 'Unverified') ?>
|
||||
<span class="stat-value <?= ($user['kyc_status'] ?? 0) == 2 ? 'success' : 'text-warning' ?>">
|
||||
<?php
|
||||
$statusMap = [0 => __('unverified'), 1 => __('pending'), 2 => __('verified'), 3 => __('rejected')];
|
||||
echo $statusMap[$user['kyc_status'] ?? 0] ?? __('unverified');
|
||||
?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
|
||||
@ -122,6 +122,83 @@ $translations = [
|
||||
'buy_up' => '买涨',
|
||||
'buy_down' => '买跌',
|
||||
'profit' => '收益',
|
||||
'enter_amount' => '请输入有效金额',
|
||||
'insufficient_balance' => '余额不足',
|
||||
'order_in_progress' => '订单进行中',
|
||||
'current_price' => '现价',
|
||||
'cycle' => '周期',
|
||||
'direction' => '方向',
|
||||
'quantity' => '数量',
|
||||
'opening_price' => '开仓价',
|
||||
'final_price_settlement' => '最终价格以系统结算为准',
|
||||
'open_orders' => '当前委托',
|
||||
'settlement_history' => '历史结算',
|
||||
'no_records_found' => '暂无记录',
|
||||
'executing' => '正在执行',
|
||||
'loss' => '亏损',
|
||||
'amount_too_low' => '买入金额低于最小限制',
|
||||
'amount_too_high' => '买入金额超过最大限制',
|
||||
'fiat_recharge' => '法币充值',
|
||||
'crypto_recharge' => '数字货币充值',
|
||||
'select_currency' => '选择币种',
|
||||
'fiat_amount' => '法币金额',
|
||||
'est_usdt' => '预计到账 (USDT)',
|
||||
'confirm_order' => '确认订单',
|
||||
'recharge_request_sent' => '充值请求已提交给客服',
|
||||
'back' => '返回',
|
||||
'network' => '网络',
|
||||
'address' => '充值地址',
|
||||
'copy' => '复制',
|
||||
'withdraw_amount' => '提现金额',
|
||||
'withdraw_address' => '提现地址',
|
||||
'receive' => '预计到账',
|
||||
'withdraw_request_sent' => '提现申请已提交,请等待审核',
|
||||
'all' => '全部',
|
||||
'crypto_withdraw' => 'USDT提现',
|
||||
'fiat_withdraw' => '法币提现',
|
||||
'withdraw_password' => '提现密码',
|
||||
'to_receive' => '预计到账',
|
||||
'est_receive_fiat' => '预计收到法币',
|
||||
'recharge_steps' => '充值步骤',
|
||||
'withdraw_steps' => '提现步骤',
|
||||
'security_tips' => '安全提示',
|
||||
'secure' => '安全',
|
||||
'fast' => '极速',
|
||||
'support_247' => '24/7支持',
|
||||
'i_have_paid' => '我已完成支付',
|
||||
'crypto_recharge_warning' => '请务必仅向此地址发送 USDT。发送其他资产可能会导致永久丢失。',
|
||||
'kyc' => '实名认证',
|
||||
'security' => '安全设置',
|
||||
'vip_level' => 'VIP等级',
|
||||
'unverified' => '未认证',
|
||||
'pending' => '审核中',
|
||||
'verified' => '已认证',
|
||||
'rejected' => '已驳回',
|
||||
'full_name' => '真实姓名',
|
||||
'id_number' => '身份证号',
|
||||
'id_front' => '身份证正面',
|
||||
'id_back' => '身份证反面',
|
||||
'id_handheld' => '手持身份证',
|
||||
'upload' => '点击上传',
|
||||
'submit' => '提交',
|
||||
'login_password' => '登录密码',
|
||||
'trade_password' => '交易密码',
|
||||
'change_password' => '修改密码',
|
||||
'set_password' => '设置密码',
|
||||
'kyc_instructions' => '请确保上传的照片清晰可见,且与填写的身份证号一致。',
|
||||
'security_instructions' => '请定期修改您的密码,并确保交易密码与登录密码不同。',
|
||||
'old_password' => '原密码',
|
||||
'new_password' => '新密码',
|
||||
'confirm_new_password' => '确认新密码',
|
||||
'kyc_steps' => '实名认证步骤',
|
||||
'kyc_step1' => '填写您的真实姓名和身份证号码。',
|
||||
'kyc_step2' => '上传您的身份证正反面照片。',
|
||||
'kyc_step3' => '上传您手持身份证的照片,并确保面部清晰。',
|
||||
'security_steps' => '安全设置步骤',
|
||||
'security_step1' => '设置强密码,包含字母、数字和符号。',
|
||||
'security_step2' => '交易密码用于提现和重要操作,请务必妥善保存。',
|
||||
'frozen' => '冻结',
|
||||
'converted_to' => '折合',
|
||||
],
|
||||
'en' => [
|
||||
'home' => 'Home',
|
||||
@ -237,6 +314,83 @@ $translations = [
|
||||
'buy_up' => 'Buy Up',
|
||||
'buy_down' => 'Buy Down',
|
||||
'profit' => 'Profit',
|
||||
'enter_amount' => 'Please enter a valid amount',
|
||||
'insufficient_balance' => 'Insufficient balance',
|
||||
'order_in_progress' => 'Order in Progress',
|
||||
'current_price' => 'Current Price',
|
||||
'cycle' => 'Cycle',
|
||||
'direction' => 'Direction',
|
||||
'quantity' => 'Quantity',
|
||||
'opening_price' => 'Opening Price',
|
||||
'final_price_settlement' => 'Final price is subject to system settlement',
|
||||
'open_orders' => 'Open Orders',
|
||||
'settlement_history' => 'Settlement History',
|
||||
'no_records_found' => 'No records found',
|
||||
'executing' => 'Executing',
|
||||
'loss' => 'Loss',
|
||||
'amount_too_low' => 'Amount too low',
|
||||
'amount_too_high' => 'Amount too high',
|
||||
'fiat_recharge' => 'Fiat Deposit',
|
||||
'crypto_recharge' => 'Crypto Deposit',
|
||||
'select_currency' => 'Select Currency',
|
||||
'fiat_amount' => 'Fiat Amount',
|
||||
'est_usdt' => 'Estimated USDT',
|
||||
'confirm_order' => 'Confirm Order',
|
||||
'recharge_request_sent' => 'Deposit request sent to support',
|
||||
'back' => 'Back',
|
||||
'network' => 'Network',
|
||||
'address' => 'Deposit Address',
|
||||
'copy' => 'Copy',
|
||||
'withdraw_amount' => 'Withdraw Amount',
|
||||
'withdraw_address' => 'Withdraw Address',
|
||||
'receive' => 'Receive',
|
||||
'withdraw_request_sent' => 'Withdrawal request submitted for review',
|
||||
'all' => 'All',
|
||||
'crypto_withdraw' => 'USDT Withdrawal',
|
||||
'fiat_withdraw' => 'Fiat Withdrawal',
|
||||
'withdraw_password' => 'Withdrawal Password',
|
||||
'to_receive' => 'To Receive',
|
||||
'est_receive_fiat' => 'Est. Fiat Receive',
|
||||
'recharge_steps' => 'Recharge Steps',
|
||||
'withdraw_steps' => 'Withdrawal Steps',
|
||||
'security_tips' => 'Security Tips',
|
||||
'secure' => 'Secure',
|
||||
'fast' => 'Fast',
|
||||
'support_247' => '24/7 Support',
|
||||
'i_have_paid' => 'I have paid',
|
||||
'crypto_recharge_warning' => 'Please only send USDT to this address. Sending other assets may result in permanent loss.',
|
||||
'kyc' => 'Identity Verification',
|
||||
'security' => 'Security Settings',
|
||||
'vip_level' => 'VIP Level',
|
||||
'unverified' => 'Unverified',
|
||||
'pending' => 'Pending',
|
||||
'verified' => 'Verified',
|
||||
'rejected' => 'Rejected',
|
||||
'full_name' => 'Full Name',
|
||||
'id_number' => 'ID Number',
|
||||
'id_front' => 'ID Front',
|
||||
'id_back' => 'ID Back',
|
||||
'id_handheld' => 'Hand-held ID',
|
||||
'upload' => 'Upload',
|
||||
'submit' => 'Submit',
|
||||
'login_password' => 'Login Password',
|
||||
'trade_password' => 'Trade Password',
|
||||
'change_password' => 'Change Password',
|
||||
'set_password' => 'Set Password',
|
||||
'kyc_instructions' => 'Please ensure that the uploaded photos are clear and consistent with the ID number filled in.',
|
||||
'security_instructions' => 'Please change your password regularly and ensure that the transaction password is different from the login password.',
|
||||
'old_password' => 'Old Password',
|
||||
'new_password' => 'New Password',
|
||||
'confirm_new_password' => 'Confirm New Password',
|
||||
'kyc_steps' => 'KYC Steps',
|
||||
'kyc_step1' => 'Fill in your real name and ID number.',
|
||||
'kyc_step2' => 'Upload photos of the front and back of your ID card.',
|
||||
'kyc_step3' => 'Upload a photo of you holding your ID card, ensuring your face is clear.',
|
||||
'security_steps' => 'Security Steps',
|
||||
'security_step1' => 'Set a strong password containing letters, numbers, and symbols.',
|
||||
'security_step2' => 'The transaction password is used for withdrawals and important operations. Please keep it safe.',
|
||||
'frozen' => 'Frozen',
|
||||
'converted_to' => 'Equivalent',
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
@ -4,6 +4,14 @@ function renderTerminal($activeTab = 'spot') {
|
||||
$currentSymbol = $_GET['symbol'] ?? 'BTC';
|
||||
$currentSymbol = strtoupper($currentSymbol);
|
||||
|
||||
$usdt_balance = 0;
|
||||
if ($user) {
|
||||
$stmt = db()->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = 'USDT'");
|
||||
$stmt->execute([$user['id']]);
|
||||
$bal = $stmt->fetch();
|
||||
$usdt_balance = $bal['available'] ?? 0;
|
||||
}
|
||||
|
||||
$full_coins = [
|
||||
['symbol' => 'BTC', 'name' => 'Bitcoin', 'price' => '64,234.50', 'change' => '+2.45%'],
|
||||
['symbol' => 'ETH', 'name' => 'Ethereum', 'price' => '3,456.20', 'change' => '+1.12%'],
|
||||
@ -113,41 +121,59 @@ function renderTerminal($activeTab = 'spot') {
|
||||
<div class="trading-panels">
|
||||
<?php if ($activeTab === 'binary'): ?>
|
||||
<div class="binary-order-panel w-100">
|
||||
<div class="section-title mb-2"><?= __('cycle_settlement') ?? 'Cycle / Settlement' ?></div>
|
||||
<div class="cycle-grid mb-3">
|
||||
<button class="cycle-btn active" onclick="selectCycle(this, 60, 8, '100-4999')">60S/8%</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 90, 12, '5000-29999')">90S/12%</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 120, 15, '30000-99999')">120S/15%</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 180, 20, '100000-299999')">180S/20%</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 300, 30, '300000+')">300S/30%</button>
|
||||
<div class="d-flex justify-content-between align-items-end mb-2">
|
||||
<div class="section-title text-white"><?= __('cycle_settlement') ?? 'Cycle / Settlement' ?></div>
|
||||
<div class="small text-white"><?= __('available_balance') ?>: <span class="text-white fw-bold balance-highlight" id="user-usdt-balance"><?= number_format($usdt_balance, 2) ?></span> USDT</div>
|
||||
</div>
|
||||
<div class="cycle-grid">
|
||||
<button class="cycle-btn active" onclick="selectCycle(this, 60, 8, 100, 4999)">
|
||||
<span class="cycle-time">60S</span>
|
||||
<span class="cycle-profit">8%</span>
|
||||
</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 90, 12, 5000, 29999)">
|
||||
<span class="cycle-time">90S</span>
|
||||
<span class="cycle-profit">12%</span>
|
||||
</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 120, 15, 30000, 99999)">
|
||||
<span class="cycle-time">120S</span>
|
||||
<span class="cycle-profit">15%</span>
|
||||
</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 180, 20, 100000, 299999)">
|
||||
<span class="cycle-time">180S</span>
|
||||
<span class="cycle-profit">20%</span>
|
||||
</button>
|
||||
<button class="cycle-btn" onclick="selectCycle(this, 300, 30, 300000, 999999999)">
|
||||
<span class="cycle-time">300S</span>
|
||||
<span class="cycle-profit">30%</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="section-title mb-2"><?= __('purchase_amount') ?? 'Purchase Amount' ?> (USDT)</div>
|
||||
<div class="section-title text-white mb-2"><?= __('purchase_amount') ?? 'Purchase Amount' ?> (USDT)</div>
|
||||
<div class="amount-input-wrapper mb-3">
|
||||
<input type="number" id="binary-amount" class="form-control bg-black text-white border-secondary" placeholder="100-4999" oninput="calculateProfit()">
|
||||
<input type="number" id="binary-amount" class="form-control" placeholder="100-4999" oninput="calculateProfit()">
|
||||
</div>
|
||||
|
||||
<div class="quick-amounts d-flex gap-2 mb-3">
|
||||
<?php foreach([10, 50, 100, 300, 500, 1000] as $amt): ?>
|
||||
<button class="btn btn-dark btn-sm flex-fill" onclick="setBinaryAmount(<?= $amt ?>)"><?= $amt ?></button>
|
||||
<?php foreach([100, 500, 1000, 5000, 10000, 50000] as $amt): ?>
|
||||
<button class="btn btn-dark btn-sm flex-fill py-2" onclick="setBinaryAmount(<?= $amt ?>)"><?= $amt ?></button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between mb-3 small align-items-center">
|
||||
<div class="text-muted"><?= __('available_balance') ?> <span class="text-white ms-1 fw-bold">1,000.00</span> USDT</div>
|
||||
<div class="text-muted"><span class="text-success fw-bold fs-6" id="profit-display">0.00</span> USDT</div>
|
||||
<div class="d-flex justify-content-between mb-3 small align-items-center bg-black bg-opacity-25 p-2 rounded">
|
||||
<div class="text-white"><?= __('expected_profit') ?? 'Expected Profit' ?></div>
|
||||
<div class="text-success fw-bold fs-6 profit-highlight" id="profit-display">0.00 USDT</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-success w-100 py-3 fw-bold rounded-3 h-100 d-flex flex-column align-items-center justify-content-center">
|
||||
<div class="fs-5"><?= __('buy_up') ?></div>
|
||||
<button onclick="placeOrder('up')" class="btn btn-success btn-buy-sell w-100 fw-bold d-flex flex-column align-items-center justify-content-center">
|
||||
<div class="fs-5"><i class="bi bi-graph-up-arrow me-1"></i><?= __('buy_up') ?></div>
|
||||
<div class="small opacity-75 fw-normal profit-rate-hint"><?= __('profit') ?> 8%</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-danger w-100 py-3 fw-bold rounded-3 h-100 d-flex flex-column align-items-center justify-content-center">
|
||||
<div class="fs-5"><?= __('buy_down') ?></div>
|
||||
<button onclick="placeOrder('down')" class="btn btn-danger btn-buy-sell w-100 fw-bold d-flex flex-column align-items-center justify-content-center">
|
||||
<div class="fs-5"><i class="bi bi-graph-down-arrow me-1"></i><?= __('buy_down') ?></div>
|
||||
<div class="small opacity-75 fw-normal profit-rate-hint"><?= __('profit') ?> 8%</div>
|
||||
</button>
|
||||
</div>
|
||||
@ -156,13 +182,21 @@ function renderTerminal($activeTab = 'spot') {
|
||||
|
||||
<script>
|
||||
let currentProfitRate = 8;
|
||||
function selectCycle(btn, seconds, profit, hint) {
|
||||
let currentSeconds = 60;
|
||||
let minAmount = 100;
|
||||
let maxAmount = 4999;
|
||||
|
||||
function selectCycle(btn, seconds, profit, min, max) {
|
||||
document.querySelectorAll('.cycle-btn').forEach(el => el.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
currentProfitRate = profit;
|
||||
currentSeconds = seconds;
|
||||
minAmount = min;
|
||||
maxAmount = max;
|
||||
|
||||
const hint = max >= 999999999 ? min + '+' : min + '-' + max;
|
||||
document.getElementById('binary-amount').placeholder = hint;
|
||||
|
||||
// Update profit hints on buttons
|
||||
document.querySelectorAll('.profit-rate-hint').forEach(el => {
|
||||
el.innerText = '<?= __("profit") ?> ' + profit + '%';
|
||||
});
|
||||
@ -179,6 +213,136 @@ function renderTerminal($activeTab = 'spot') {
|
||||
const profit = (amount * currentProfitRate / 100).toFixed(2);
|
||||
document.getElementById('profit-display').innerText = profit + ' USDT';
|
||||
}
|
||||
|
||||
function placeOrder(direction) {
|
||||
const amount = parseFloat(document.getElementById('binary-amount').value);
|
||||
const balance = parseFloat(document.getElementById('user-usdt-balance').innerText.replace(',', ''));
|
||||
|
||||
if (!amount || amount <= 0) {
|
||||
alert('<?= __("enter_amount") ?? "Please enter a valid amount" ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount < minAmount) {
|
||||
alert('<?= __("amount_too_low") ?> (' + minAmount + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount > maxAmount) {
|
||||
alert('<?= __("amount_too_high") ?> (' + maxAmount + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount > balance) {
|
||||
alert('<?= __("insufficient_balance") ?? "Insufficient balance" ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
const openPrice = document.querySelector('.price-jump').innerText;
|
||||
|
||||
// Simulation of order placement
|
||||
const order = {
|
||||
id: Math.floor(Math.random() * 1000000),
|
||||
time: new Date().toISOString().replace('T', ' ').substr(0, 19),
|
||||
pair: '<?= $currentSymbol ?>/USDT',
|
||||
type: 'Binary',
|
||||
side: direction === 'up' ? '<?= __("buy_up") ?>' : '<?= __("buy_down") ?>',
|
||||
side_type: direction,
|
||||
price: openPrice,
|
||||
amount: amount.toFixed(2),
|
||||
total: '---',
|
||||
status: 'Executing',
|
||||
secondsLeft: currentSeconds,
|
||||
totalSeconds: currentSeconds,
|
||||
profitRate: currentProfitRate
|
||||
};
|
||||
|
||||
historyData.open.unshift(order);
|
||||
showHistoryTab('open');
|
||||
|
||||
// Show Popup
|
||||
showOrderPopup(order);
|
||||
|
||||
// Deduct balance visually
|
||||
document.getElementById('user-usdt-balance').innerText = (balance - amount).toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
|
||||
// Timer for settlement
|
||||
const timer = setInterval(() => {
|
||||
order.secondsLeft--;
|
||||
|
||||
// Update popup
|
||||
updateOrderPopup(order);
|
||||
|
||||
if (showHistoryTab.currentTab === 'open') showHistoryTab('open');
|
||||
|
||||
if (order.secondsLeft <= 0) {
|
||||
clearInterval(timer);
|
||||
settleOrder(order);
|
||||
hideOrderPopup();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function showOrderPopup(order) {
|
||||
const popup = document.getElementById('order-popup-overlay');
|
||||
const sideColor = order.side.includes('Up') || order.side.includes('涨') ? '#26a69a' : '#ef5350';
|
||||
|
||||
document.getElementById('popup-price').innerText = order.price;
|
||||
document.getElementById('popup-cycle').innerText = order.totalSeconds + 's';
|
||||
document.getElementById('popup-direction').innerText = order.side;
|
||||
document.getElementById('popup-direction').style.color = sideColor;
|
||||
document.getElementById('popup-quantity').innerText = order.amount + ' USDT';
|
||||
document.getElementById('popup-open-price').innerText = order.price;
|
||||
|
||||
popup.style.display = 'flex';
|
||||
updateOrderPopup(order);
|
||||
}
|
||||
|
||||
function updateOrderPopup(order) {
|
||||
const timeText = document.getElementById('popup-time-text');
|
||||
const progress = document.getElementById('popup-progress');
|
||||
const currentPrice = document.getElementById('popup-price');
|
||||
|
||||
timeText.innerText = order.secondsLeft + 's';
|
||||
|
||||
// Update current price in popup
|
||||
currentPrice.innerText = document.querySelector('.price-jump').innerText;
|
||||
|
||||
const radius = 70;
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
const offset = circumference - (order.secondsLeft / order.totalSeconds) * circumference;
|
||||
|
||||
progress.style.strokeDasharray = `${circumference} ${circumference}`;
|
||||
progress.style.strokeDashoffset = offset;
|
||||
}
|
||||
|
||||
function hideOrderPopup() {
|
||||
document.getElementById('order-popup-overlay').style.display = 'none';
|
||||
}
|
||||
|
||||
function settleOrder(order) {
|
||||
const isWin = Math.random() > 0.45; // 55% win rate for simulation
|
||||
const amount = parseFloat(order.amount);
|
||||
const profit = isWin ? (amount * order.profitRate / 100) : -amount;
|
||||
|
||||
order.status = isWin ? 'Profit' : 'Loss';
|
||||
order.total = isWin ? (amount + profit).toFixed(2) : '0.00';
|
||||
order.timeSettled = new Date().toISOString().replace('T', ' ').substr(0, 19);
|
||||
|
||||
// Move from open to settlement
|
||||
historyData.open = historyData.open.filter(o => o.id !== order.id);
|
||||
historyData.settlement.unshift(order);
|
||||
|
||||
if (showHistoryTab.currentTab === 'open' || showHistoryTab.currentTab === 'settlement') {
|
||||
showHistoryTab(showHistoryTab.currentTab);
|
||||
}
|
||||
|
||||
// Update balance visually if win
|
||||
if (isWin) {
|
||||
const balance = parseFloat(document.getElementById('user-usdt-balance').innerText.replace(',', ''));
|
||||
document.getElementById('user-usdt-balance').innerText = (balance + amount + profit).toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php else: ?>
|
||||
@ -188,7 +352,7 @@ function renderTerminal($activeTab = 'spot') {
|
||||
<button class="active btn btn-sm btn-outline-secondary py-1 px-3">Limit</button>
|
||||
<button class="btn btn-sm btn-outline-secondary py-1 px-3">Market</button>
|
||||
</div>
|
||||
<div class="small text-muted"><?= __('assets') ?>: <span class="text-white">1,000.00 USDT</span></div>
|
||||
<div class="small text-muted"><?= __('assets') ?>: <span class="text-white"><?= number_format($usdt_balance, 2) ?> USDT</span></div>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-6">
|
||||
@ -241,26 +405,68 @@ function renderTerminal($activeTab = 'spot') {
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Simulating price jump
|
||||
setInterval(() => {
|
||||
const el = document.querySelector('.price-jump');
|
||||
if (!el) return;
|
||||
const current = parseFloat(el.innerText.replace(',', ''));
|
||||
const diff = (Math.random() - 0.5) * 10;
|
||||
const next = (current + diff).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
|
||||
el.innerText = next;
|
||||
el.style.color = diff > 0 ? '#26a69a' : '#ef5350';
|
||||
setTimeout(() => el.style.color = '#26a69a', 500);
|
||||
}, 2000);
|
||||
// Real-time market price fetcher
|
||||
async function updateMarketPrices() {
|
||||
try {
|
||||
const response = await fetch('https://api.binance.com/api/v3/ticker/24hr');
|
||||
const data = await response.json();
|
||||
const prices = {};
|
||||
data.forEach(item => {
|
||||
if (item.symbol.endsWith('USDT')) {
|
||||
const base = item.symbol.replace('USDT', '');
|
||||
prices[base] = {
|
||||
price: parseFloat(item.lastPrice),
|
||||
change: item.priceChangePercent
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Update Sidebar
|
||||
document.querySelectorAll('.coin-row').forEach(row => {
|
||||
const symbol = row.querySelector('.symbol').innerText;
|
||||
if (prices[symbol]) {
|
||||
const p = prices[symbol].price;
|
||||
const c = prices[symbol].change;
|
||||
row.querySelector('.price').innerText = p < 1 ? p.toFixed(6) : p.toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
const changeEl = row.querySelector('.change');
|
||||
changeEl.innerText = (c > 0 ? '+' : '') + c + '%';
|
||||
changeEl.className = 'change ' + (c >= 0 ? 'text-success' : 'text-danger');
|
||||
}
|
||||
});
|
||||
|
||||
// Update Header for current symbol
|
||||
const currentSymbol = '<?= $currentSymbol ?>';
|
||||
if (prices[currentSymbol]) {
|
||||
const p = prices[currentSymbol].price;
|
||||
const c = prices[currentSymbol].change;
|
||||
const priceEl = document.querySelector('.price-jump');
|
||||
if (priceEl) {
|
||||
const oldPrice = parseFloat(priceEl.innerText.replace(',', ''));
|
||||
priceEl.innerText = p < 1 ? p.toFixed(6) : p.toLocaleString('en-US', {minimumFractionDigits: 2});
|
||||
priceEl.style.color = p >= oldPrice ? '#26a69a' : '#ef5350';
|
||||
setTimeout(() => priceEl.style.color = '#26a69a', 800);
|
||||
}
|
||||
|
||||
const headerStats = document.querySelectorAll('.header-stat span');
|
||||
if (headerStats[1]) {
|
||||
headerStats[1].innerText = (c > 0 ? '+' : '') + c + '%';
|
||||
headerStats[1].className = (c >= 0 ? 'text-success' : 'text-danger') + ' fw-bold';
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch prices", e);
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(updateMarketPrices, 3000);
|
||||
updateMarketPrices();
|
||||
</script>
|
||||
|
||||
|
||||
<div class="order-history p-0">
|
||||
<div class="d-flex gap-0 border-bottom border-secondary bg-dark history-tabs">
|
||||
<h6 class="px-4 py-3 mb-0 active text-primary bg-black" onclick="showHistoryTab('open')" id="tab-open" style="cursor: pointer; font-size: 13px; font-weight: bold; border-bottom: 2px solid var(--term-primary) !important;">当前委托 (Open Orders)</h6>
|
||||
<h6 class="px-4 py-3 mb-0 text-muted" onclick="showHistoryTab('settlement')" id="tab-settlement" style="cursor: pointer; font-size: 13px;">结算部位 (Settlement)</h6>
|
||||
<h6 class="px-4 py-3 mb-0 text-muted" onclick="showHistoryTab('history')" id="tab-history" style="cursor: pointer; font-size: 13px;">成交历史 (Trade History)</h6>
|
||||
<h6 class="px-4 py-3 mb-0 text-muted" onclick="showHistoryTab('assets')" id="tab-assets" style="cursor: pointer; font-size: 13px;">资产 (Assets)</h6>
|
||||
<h6 class="px-4 py-3 mb-0 active text-white bg-black" onclick="showHistoryTab('open')" id="tab-open" style="cursor: pointer; font-size: 13px; font-weight: bold; border-bottom: 2px solid var(--term-primary) !important;"><?= __('open_orders') ?></h6>
|
||||
<h6 class="px-4 py-3 mb-0 text-white opacity-75" onclick="showHistoryTab('settlement')" id="tab-settlement" style="cursor: pointer; font-size: 13px;"><?= __('settlement_history') ?></h6>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-dark table-sm mb-0" id="history-table" style="font-size: 12px;">
|
||||
@ -329,56 +535,72 @@ function renderTerminal($activeTab = 'spot') {
|
||||
|
||||
<script>
|
||||
const historyData = {
|
||||
open: [
|
||||
{time: '2026-02-16 15:45:12', pair: 'BTC/USDT', type: 'Limit', side: 'Buy', price: '64,100.00', amount: '0.5000', total: '32,050.00', status: 'Pending'},
|
||||
{time: '2026-02-16 15:40:05', pair: '<?= $currentSymbol ?>/USDT', type: 'Limit', side: 'Sell', price: '64,500.00', amount: '0.2500', total: '16,125.00', status: 'Pending'}
|
||||
],
|
||||
settlement: [
|
||||
{time: '2026-02-16 14:30:11', pair: 'BTC/USDT', type: 'Binary', side: 'Buy Up', price: '64,234.50', amount: '100.00', total: '108.00', status: 'Profit'},
|
||||
{time: '2026-02-16 13:15:22', pair: 'ETH/USDT', type: 'Binary', side: 'Buy Down', price: '3,456.20', amount: '50.00', total: '0.00', status: 'Loss'}
|
||||
],
|
||||
history: [
|
||||
{time: '2026-02-16 12:00:00', pair: 'SOL/USDT', type: 'Market', side: 'Buy', price: '142.30', amount: '100.00', total: '14,230.00', status: 'Filled'}
|
||||
],
|
||||
assets: [
|
||||
{time: '-', pair: 'USDT', type: 'Wallet', side: '-', price: '1.00', amount: '1,000.00', total: '1,000.00', status: 'Available'},
|
||||
{time: '-', pair: 'BTC', type: 'Wallet', side: '-', price: '64,234.50', amount: '0.0500', total: '3,211.73', status: 'Available'}
|
||||
]
|
||||
open: [],
|
||||
settlement: []
|
||||
};
|
||||
|
||||
function showHistoryTab(tab) {
|
||||
showHistoryTab.currentTab = tab;
|
||||
// Update tabs UI
|
||||
document.querySelectorAll('.history-tabs h6').forEach(el => {
|
||||
el.classList.remove('active', 'text-primary', 'bg-black');
|
||||
el.classList.add('text-muted');
|
||||
el.classList.remove('active', 'text-white', 'bg-black', 'opacity-100');
|
||||
el.classList.add('text-white', 'opacity-75');
|
||||
el.style.borderBottom = 'none';
|
||||
});
|
||||
const activeTab = document.getElementById('tab-' + tab);
|
||||
activeTab.classList.add('active', 'text-primary', 'bg-black');
|
||||
activeTab.classList.remove('text-muted');
|
||||
activeTab.style.borderBottom = '2px solid var(--term-primary)';
|
||||
if (activeTab) {
|
||||
activeTab.classList.add('active', 'text-white', 'bg-black', 'opacity-100');
|
||||
activeTab.classList.remove('opacity-75');
|
||||
activeTab.style.borderBottom = '2px solid var(--term-primary)';
|
||||
}
|
||||
|
||||
// Update table content
|
||||
const body = document.getElementById('history-body');
|
||||
body.innerHTML = '';
|
||||
|
||||
if (!historyData[tab] || historyData[tab].length === 0) {
|
||||
body.innerHTML = '<tr><td colspan="9" class="text-center py-5 text-muted">No records found</td></tr>';
|
||||
body.innerHTML = '<tr><td colspan="9" class="text-center py-5 text-muted"><?= __("no_records_found") ?? "No records found" ?></td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
historyData[tab].forEach(row => {
|
||||
const tr = document.createElement('tr');
|
||||
const isProfit = row.status === 'Profit';
|
||||
const isLoss = row.status === 'Loss';
|
||||
const isExecuting = row.status === 'Executing';
|
||||
|
||||
const statusClass = isProfit ? 'text-success' : (isLoss ? 'text-danger' : 'text-info');
|
||||
const statusBg = isProfit ? 'bg-success' : (isLoss ? 'bg-danger' : 'bg-info');
|
||||
|
||||
let displayStatus = row.status;
|
||||
if (isExecuting) displayStatus = '<?= __("executing") ?? "Executing" ?> (' + row.secondsLeft + 's)';
|
||||
if (isProfit) displayStatus = '<?= __("profit") ?>';
|
||||
if (isLoss) displayStatus = '<?= __("loss") ?? "Loss" ?>';
|
||||
|
||||
// Format total/profit for settled orders
|
||||
let totalDisplay = row.total;
|
||||
if (tab === 'settlement' && (isProfit || isLoss)) {
|
||||
const amount = parseFloat(row.amount);
|
||||
const total = parseFloat(row.total);
|
||||
const pl = (total - amount).toFixed(2);
|
||||
const plClass = pl >= 0 ? 'text-success' : 'text-danger';
|
||||
totalDisplay = `<div class="${plClass} fw-bold">${total.toFixed(2)}</div><div class="small opacity-75">${pl >= 0 ? '+' : ''}${pl}</div>`;
|
||||
}
|
||||
|
||||
const isUp = row.side_type === 'up' || row.side.includes('Up') || row.side.includes('涨') || row.side === 'Buy';
|
||||
|
||||
tr.innerHTML = `
|
||||
<td class="ps-3 py-3 text-muted">${row.time}</td>
|
||||
<td class="ps-3 py-3 text-muted" style="font-size: 11px;">${row.time}</td>
|
||||
<td class="py-3 fw-bold text-white">${row.pair}</td>
|
||||
<td class="py-3">${row.type}</td>
|
||||
<td class="py-3 ${row.side === 'Buy' ? 'text-success' : (row.side === 'Sell' ? 'text-danger' : 'text-white')}">${row.side}</td>
|
||||
<td class="py-3"><span class="small bg-secondary bg-opacity-25 px-1 rounded">${row.type}</span></td>
|
||||
<td class="py-3 ${isUp ? 'text-success' : 'text-danger'}">
|
||||
<i class="bi bi-graph-${isUp ? 'up' : 'down'} me-1"></i>${row.side}
|
||||
</td>
|
||||
<td class="py-3">${row.price}</td>
|
||||
<td class="py-3">${row.amount}</td>
|
||||
<td class="py-3">${row.total}</td>
|
||||
<td class="py-3"><span class="badge bg-success bg-opacity-10 text-success">${row.status}</span></td>
|
||||
<td class="pe-3 py-3 text-end"><button class="btn btn-sm btn-link text-muted p-0">Details</button></td>
|
||||
<td class="py-3">${totalDisplay}</td>
|
||||
<td class="py-3"><span class="badge ${statusBg} bg-opacity-10 ${statusClass} rounded-pill px-2" style="font-size: 10px;">${displayStatus}</span></td>
|
||||
<td class="pe-3 py-3 text-end"><button class="btn btn-sm btn-dark px-2 py-0" style="font-size: 10px;">Details</button></td>
|
||||
`;
|
||||
body.appendChild(tr);
|
||||
});
|
||||
@ -387,6 +609,48 @@ function renderTerminal($activeTab = 'spot') {
|
||||
// Initialize with open orders
|
||||
showHistoryTab('open');
|
||||
</script>
|
||||
|
||||
<!-- Order Countdown Popup Modal -->
|
||||
<div class="order-popup-overlay" id="order-popup-overlay">
|
||||
<div class="order-popup">
|
||||
<h5><?= __('order_in_progress') ?></h5>
|
||||
|
||||
<div class="countdown-circle">
|
||||
<svg>
|
||||
<circle class="bg" cx="80" cy="80" r="70"></circle>
|
||||
<circle class="progress" id="popup-progress" cx="80" cy="80" r="70"></circle>
|
||||
</svg>
|
||||
<div class="time-text" id="popup-time-text">60s</div>
|
||||
</div>
|
||||
|
||||
<div class="popup-details">
|
||||
<div class="popup-row">
|
||||
<span class="label"><?= __('current_price') ?></span>
|
||||
<span class="value" id="popup-price">---</span>
|
||||
</div>
|
||||
<div class="popup-row">
|
||||
<span class="label"><?= __('cycle') ?></span>
|
||||
<span class="value" id="popup-cycle">60s</span>
|
||||
</div>
|
||||
<div class="popup-row">
|
||||
<span class="label"><?= __('direction') ?></span>
|
||||
<span class="value" id="popup-direction">---</span>
|
||||
</div>
|
||||
<div class="popup-row">
|
||||
<span class="label"><?= __('quantity') ?></span>
|
||||
<span class="value" id="popup-quantity">---</span>
|
||||
</div>
|
||||
<div class="popup-row">
|
||||
<span class="label"><?= __('opening_price') ?></span>
|
||||
<span class="value" id="popup-open-price">---</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="popup-footer">
|
||||
<?= __('final_price_settlement') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
203
kyc.php
Normal file
203
kyc.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
include __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!$user) {
|
||||
header('Location: /auth/login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$stmt->execute([$user['id']]);
|
||||
$userData = $stmt->fetch();
|
||||
|
||||
$success = '';
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$real_name = $_POST['real_name'] ?? '';
|
||||
$id_number = $_POST['id_number'] ?? '';
|
||||
|
||||
// Handle uploads
|
||||
$uploadDir = 'uploads/kyc/';
|
||||
if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
|
||||
|
||||
$front = $userData['kyc_photo_front'];
|
||||
$back = $userData['kyc_photo_back'];
|
||||
$handheld = $userData['kyc_photo_handheld'];
|
||||
|
||||
if (isset($_FILES['photo_front']) && $_FILES['photo_front']['error'] === 0) {
|
||||
$ext = pathinfo($_FILES['photo_front']['name'], PATHINFO_EXTENSION);
|
||||
$front = $uploadDir . $user['id'] . '_front_' . time() . '.' . $ext;
|
||||
move_uploaded_file($_FILES['photo_front']['tmp_name'], $front);
|
||||
}
|
||||
|
||||
if (isset($_FILES['photo_back']) && $_FILES['photo_back']['error'] === 0) {
|
||||
$ext = pathinfo($_FILES['photo_back']['name'], PATHINFO_EXTENSION);
|
||||
$back = $uploadDir . $user['id'] . '_back_' . time() . '.' . $ext;
|
||||
move_uploaded_file($_FILES['photo_back']['tmp_name'], $back);
|
||||
}
|
||||
|
||||
if (isset($_FILES['photo_handheld']) && $_FILES['photo_handheld']['error'] === 0) {
|
||||
$ext = pathinfo($_FILES['photo_handheld']['name'], PATHINFO_EXTENSION);
|
||||
$handheld = $uploadDir . $user['id'] . '_handheld_' . time() . '.' . $ext;
|
||||
move_uploaded_file($_FILES['photo_handheld']['tmp_name'], $handheld);
|
||||
}
|
||||
|
||||
if (empty($real_name) || empty($id_number)) {
|
||||
$error = "Please fill in all fields";
|
||||
} else {
|
||||
$stmt = db()->prepare("UPDATE users SET kyc_name = ?, kyc_id_number = ?, kyc_photo_front = ?, kyc_photo_back = ?, kyc_photo_handheld = ?, kyc_status = 1 WHERE id = ?");
|
||||
$stmt->execute([$real_name, $id_number, $front, $back, $handheld, $user['id']]);
|
||||
$success = "Verification request submitted successfully!";
|
||||
// Refresh user data
|
||||
$userData['kyc_status'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$kycStatus = $userData['kyc_status'] ?? 0;
|
||||
?>
|
||||
|
||||
<div class="container py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="mb-4">
|
||||
<a href="/profile.php" class="text-white-50 text-decoration-none d-inline-flex align-items-center gap-2">
|
||||
<i class="bi bi-arrow-left fs-4"></i>
|
||||
<span><?= __('back') ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card bg-surface border-secondary rounded-4 shadow-lg overflow-hidden">
|
||||
<div class="card-header border-secondary bg-black bg-opacity-20 p-4">
|
||||
<h4 class="mb-0 fw-bold d-flex align-items-center gap-3 text-white">
|
||||
<i class="bi bi-person-vcard text-primary"></i>
|
||||
<?= __('kyc') ?>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4 p-md-5">
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success border-0 bg-success bg-opacity-10 text-success rounded-4 mb-4">
|
||||
<i class="bi bi-check-circle-fill me-2"></i><?= $success ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger border-0 bg-danger bg-opacity-10 text-danger rounded-4 mb-4">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i><?= $error ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($kycStatus == 2): ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-patch-check-fill text-success" style="font-size: 80px;"></i>
|
||||
<h3 class="text-white fw-bold mt-4"><?= __('verified') ?></h3>
|
||||
<p class="text-white-50"><?= htmlspecialchars($userData['kyc_name']) ?> (<?= htmlspecialchars($userData['kyc_id_number']) ?>)</p>
|
||||
</div>
|
||||
<?php elseif ($kycStatus == 1): ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-clock-history text-warning" style="font-size: 80px;"></i>
|
||||
<h3 class="text-white fw-bold mt-4"><?= __('pending') ?></h3>
|
||||
<p class="text-white-50">Your application is being reviewed by our team.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<form method="POST" enctype="multipart/form-data">
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('full_name') ?></label>
|
||||
<input type="text" name="real_name" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="Enter your full name" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('id_number') ?></label>
|
||||
<input type="text" name="id_number" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="Enter your ID number" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-5">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('id_front') ?></label>
|
||||
<div class="upload-area border-secondary rounded-4 p-4 text-center border-dashed position-relative" style="border: 2px dashed #2b3139; cursor: pointer;">
|
||||
<input type="file" name="photo_front" class="position-absolute w-100 h-100 top-0 start-0 opacity-0" style="cursor: pointer;" required onchange="previewImg(this)">
|
||||
<div class="preview-content">
|
||||
<i class="bi bi-image text-white-50 fs-1 mb-2 d-block"></i>
|
||||
<span class="text-white-50 small"><?= __('upload') ?></span>
|
||||
</div>
|
||||
<img class="img-preview d-none w-100 rounded-3 shadow" style="object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('id_back') ?></label>
|
||||
<div class="upload-area border-secondary rounded-4 p-4 text-center border-dashed position-relative" style="border: 2px dashed #2b3139; cursor: pointer;">
|
||||
<input type="file" name="photo_back" class="position-absolute w-100 h-100 top-0 start-0 opacity-0" style="cursor: pointer;" required onchange="previewImg(this)">
|
||||
<div class="preview-content">
|
||||
<i class="bi bi-image text-white-50 fs-1 mb-2 d-block"></i>
|
||||
<span class="text-white-50 small"><?= __('upload') ?></span>
|
||||
</div>
|
||||
<img class="img-preview d-none w-100 rounded-3 shadow" style="object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('id_handheld') ?></label>
|
||||
<div class="upload-area border-secondary rounded-4 p-4 text-center border-dashed position-relative" style="border: 2px dashed #2b3139; cursor: pointer;">
|
||||
<input type="file" name="photo_handheld" class="position-absolute w-100 h-100 top-0 start-0 opacity-0" style="cursor: pointer;" required onchange="previewImg(this)">
|
||||
<div class="preview-content">
|
||||
<i class="bi bi-image text-white-50 fs-1 mb-2 d-block"></i>
|
||||
<span class="text-white-50 small"><?= __('upload') ?></span>
|
||||
</div>
|
||||
<img class="img-preview d-none w-100 rounded-3 shadow" style="object-fit: cover;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-black bg-opacity-20 rounded-4 p-4 mb-5 border border-secondary border-opacity-50">
|
||||
<h6 class="text-white fw-bold mb-3 d-flex align-items-center gap-2">
|
||||
<i class="bi bi-info-circle text-primary"></i> <?= __('kyc_steps') ?>
|
||||
</h6>
|
||||
<ul class="text-white-50 small mb-0 ps-3">
|
||||
<li class="mb-2"><?= __('kyc_step1') ?></li>
|
||||
<li class="mb-2"><?= __('kyc_step2') ?></li>
|
||||
<li><?= __('kyc_step3') ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-primary">
|
||||
<?= __('submit') ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Additional Instructions Section -->
|
||||
<div class="card bg-surface border-secondary rounded-4 mt-4">
|
||||
<div class="card-body p-4">
|
||||
<h6 class="text-white fw-bold mb-3"><i class="bi bi-shield-check text-success me-2"></i> <?= __('kyc_instructions') ?? 'Certification Instructions' ?></h6>
|
||||
<p class="text-white-50 small mb-0">
|
||||
<?= __('kyc_instructions') ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function previewImg(input) {
|
||||
if (input.files && input.files[0]) {
|
||||
var reader = new FileReader();
|
||||
var parent = input.closest('.upload-area');
|
||||
var preview = parent.querySelector('.img-preview');
|
||||
var content = parent.querySelector('.preview-content');
|
||||
|
||||
reader.onload = function(e) {
|
||||
preview.src = e.target.result;
|
||||
preview.classList.remove('d-none');
|
||||
content.classList.add('d-none');
|
||||
}
|
||||
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php include __DIR__ . '/includes/footer.php'; ?>
|
||||
226
profile.php
226
profile.php
@ -6,113 +6,163 @@ if (!$user) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Get user data again to ensure we have latest fields
|
||||
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$stmt->execute([$user['id']]);
|
||||
$userData = $stmt->fetch();
|
||||
|
||||
// Get balances
|
||||
$stmt = db()->prepare("SELECT * FROM user_balances WHERE user_id = ?");
|
||||
$stmt->execute([$user['id']]);
|
||||
$balances = $stmt->fetchAll();
|
||||
|
||||
// Total USDT Balance calculation
|
||||
$totalBalanceUsdt = 0;
|
||||
foreach ($balances as $b) {
|
||||
if ($b['symbol'] === 'USDT') {
|
||||
$totalBalanceUsdt += $b['available'] + $b['frozen'];
|
||||
}
|
||||
}
|
||||
|
||||
function getVipLevel($totalRecharge) {
|
||||
if ($totalRecharge >= 10000000) return 7;
|
||||
if ($totalRecharge >= 5000000) return 6;
|
||||
if ($totalRecharge >= 1000000) return 5;
|
||||
if ($totalRecharge >= 500000) return 4;
|
||||
if ($totalRecharge >= 100000) return 3;
|
||||
if ($totalRecharge >= 50000) return 2;
|
||||
if ($totalRecharge >= 10001) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
$vipLevel = getVipLevel($userData['total_recharge'] ?? 0);
|
||||
|
||||
$kycStatusText = [
|
||||
0 => __('unverified'),
|
||||
1 => __('pending'),
|
||||
2 => __('verified'),
|
||||
3 => __('rejected')
|
||||
];
|
||||
$kycStatusColor = [
|
||||
0 => 'text-white-50',
|
||||
1 => 'text-warning',
|
||||
2 => 'text-success',
|
||||
3 => 'text-danger'
|
||||
];
|
||||
?>
|
||||
|
||||
<div class="container py-5">
|
||||
<div class="container py-4">
|
||||
<div class="row g-4">
|
||||
<!-- User Info Card -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card bg-dark border-0 shadow-lg h-100" style="background: #161a1e !important; border: 1px solid #2b3139 !important; border-radius: 24px;">
|
||||
<div class="card-body p-4 text-center">
|
||||
<div class="position-relative d-inline-block mb-3">
|
||||
<div class="rounded-circle bg-primary d-flex align-items-center justify-content-center text-white shadow-lg" style="width: 100px; height: 100px; font-size: 40px; background: linear-gradient(135deg, #0062ff, #00d2ff) !important;">
|
||||
<?= strtoupper(substr($user['username'], 0, 1)) ?>
|
||||
</div>
|
||||
<div class="position-absolute bottom-0 end-0 bg-success border border-4 border-dark rounded-circle" style="width: 25px; height: 25px;"></div>
|
||||
</div>
|
||||
<h3 class="fw-bold text-white mb-1"><?= htmlspecialchars($user['username']) ?></h3>
|
||||
<p class="text-muted small mb-4"><?= htmlspecialchars($user['email'] ?? 'No email linked') ?></p>
|
||||
|
||||
<div class="bg-black bg-opacity-25 rounded-4 p-3 mb-4 text-start border border-secondary border-opacity-25">
|
||||
<div class="d-flex justify-content-between mb-2 small">
|
||||
<span class="text-muted">UID</span>
|
||||
<span class="text-white fw-bold"><?= $user['uid'] ?? ($user['id'] + 10000) ?></span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2 small">
|
||||
<span class="text-muted">Account Status</span>
|
||||
<span class="text-success fw-bold"><i class="bi bi-patch-check-fill me-1"></i>Verified</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between small">
|
||||
<span class="text-muted">Credit Score</span>
|
||||
<span class="text-primary fw-bold"><?= $user['credit_score'] ?? 80 ?></span>
|
||||
<!-- Sidebar -->
|
||||
<div class="col-lg-3">
|
||||
<div class="card bg-surface border-secondary rounded-4 overflow-hidden h-100">
|
||||
<div class="card-body p-0">
|
||||
<!-- User Header -->
|
||||
<div class="p-4 text-center border-bottom border-secondary bg-black bg-opacity-20">
|
||||
<div class="avatar-wrapper mb-3 mx-auto">
|
||||
<div class="rounded-circle bg-primary bg-gradient d-flex align-items-center justify-content-center text-white shadow" style="width: 80px; height: 80px; font-size: 32px;">
|
||||
<?= strtoupper(substr($userData['username'], 0, 1)) ?>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="fw-bold text-white mb-0"><?= htmlspecialchars($userData['username']) ?></h5>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<button class="btn btn-outline-secondary rounded-pill py-2 small fw-bold">Security Settings</button>
|
||||
<button class="btn btn-outline-danger border-0 rounded-pill py-2 small fw-bold" onclick="location.href='/auth/logout.php'">Logout</button>
|
||||
<!-- Menu List -->
|
||||
<div class="list-group list-group-flush bg-transparent">
|
||||
<div class="list-group-item bg-transparent border-secondary py-3 d-flex justify-content-between align-items-center">
|
||||
<span class="text-white-50 small"><i class="bi bi-person-badge me-2 text-primary"></i>UID</span>
|
||||
<span class="text-white fw-bold small"><?= $userData['uid'] ?></span>
|
||||
</div>
|
||||
<div class="list-group-item bg-transparent border-secondary py-3 d-flex justify-content-between align-items-center">
|
||||
<span class="text-white-50 small"><i class="bi bi-shield-check me-2 text-info"></i><?= __('credit_score') ?></span>
|
||||
<span class="text-info fw-bold small"><?= $userData['credit_score'] ?></span>
|
||||
</div>
|
||||
<div class="list-group-item bg-transparent border-secondary py-3 d-flex justify-content-between align-items-center">
|
||||
<span class="text-white-50 small"><i class="bi bi-gem me-2 text-warning"></i><?= __('vip_level') ?></span>
|
||||
<span class="badge bg-warning text-dark fw-bold">VIP <?= $vipLevel ?></span>
|
||||
</div>
|
||||
|
||||
<a href="/kyc.php" class="list-group-item list-group-item-action bg-transparent border-secondary py-3 d-flex justify-content-between align-items-center text-white">
|
||||
<span class="text-white-50 small"><i class="bi bi-person-vcard me-2 text-success"></i><?= __('kyc') ?></span>
|
||||
<span class="small <?= $kycStatusColor[$userData['kyc_status'] ?? 0] ?>">
|
||||
<?= $kycStatusText[$userData['kyc_status'] ?? 0] ?> <i class="bi bi-chevron-right ms-1"></i>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<a href="/security.php" class="list-group-item list-group-item-action bg-transparent border-secondary py-3 d-flex justify-content-between align-items-center text-white">
|
||||
<span class="text-white-50 small"><i class="bi bi-lock me-2 text-danger"></i><?= __('security') ?></span>
|
||||
<span class="text-white-50 small"><i class="bi bi-chevron-right"></i></span>
|
||||
</a>
|
||||
|
||||
<a href="/auth/logout.php" class="list-group-item list-group-item-action bg-transparent border-0 py-3 d-flex justify-content-between align-items-center text-danger">
|
||||
<span class="small"><i class="bi bi-box-arrow-right me-2"></i><?= __('logout') ?></span>
|
||||
<span class="small"><i class="bi bi-chevron-right"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Assets Card -->
|
||||
<div class="col-lg-8">
|
||||
<div class="card bg-dark border-0 shadow-lg h-100" style="background: #161a1e !important; border: 1px solid #2b3139 !important; border-radius: 24px;">
|
||||
<!-- Main Content -->
|
||||
<div class="col-lg-9">
|
||||
<!-- Asset Summary -->
|
||||
<div class="card bg-surface border-secondary rounded-4 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h4 class="fw-bold text-white m-0">Wallet Balances</h4>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary btn-sm px-3 rounded-pill me-2"><?= __('deposit') ?></button>
|
||||
<button class="btn btn-outline-light btn-sm px-3 rounded-pill"><?= __('withdraw') ?></button>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-6">
|
||||
<p class="text-white-50 small mb-1"><?= __('balance') ?> (USDT)</p>
|
||||
<h2 class="text-white fw-bold mb-0">≈ <?= number_format($totalBalanceUsdt, 2) ?> <span class="fs-6 fw-normal text-white-50">USDT</span></h2>
|
||||
</div>
|
||||
<div class="col-md-6 text-md-end mt-3 mt-md-0">
|
||||
<a href="/recharge.php" class="btn btn-primary rounded-pill px-4 me-2">
|
||||
<i class="bi bi-plus-circle me-2"></i><?= __('deposit') ?>
|
||||
</a>
|
||||
<a href="/withdraw.php" class="btn btn-outline-light rounded-pill px-4">
|
||||
<i class="bi bi-arrow-up-circle me-2"></i><?= __('withdraw') ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-dark table-hover mb-0 align-middle">
|
||||
<thead style="background: rgba(255,255,255,0.02);">
|
||||
<tr class="text-muted small border-0">
|
||||
<th class="ps-3 py-3 border-0">Asset</th>
|
||||
<th class="py-3 border-0 text-center">Icon</th>
|
||||
<th class="py-3 border-0">Available</th>
|
||||
<th class="py-3 border-0">Frozen</th>
|
||||
<th class="text-end pe-3 py-3 border-0">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="border-0">
|
||||
<?php
|
||||
$icons = [
|
||||
'USDT' => '325/small/tether.png',
|
||||
'BTC' => '1/small/bitcoin.png',
|
||||
'ETH' => '279/small/ethereum.png',
|
||||
'BNB' => '825/small/binance-coin-logo.png'
|
||||
];
|
||||
foreach($balances as $b):
|
||||
?>
|
||||
<tr style="border-bottom: 1px solid rgba(255,255,255,0.05);">
|
||||
<td class="ps-3 py-4 border-0">
|
||||
<div class="fw-bold text-white fs-5"><?= $b['symbol'] ?></div>
|
||||
</td>
|
||||
<td class="py-4 border-0 text-center">
|
||||
<img src="<?= getCoinIcon($b['symbol']) ?>" width="24" height="24">
|
||||
</td>
|
||||
<td class="py-4 border-0">
|
||||
<div class="fw-bold text-white"><?= number_format((float)$b['available'], 4) ?></div>
|
||||
</td>
|
||||
<td class="py-4 border-0 text-muted small">
|
||||
<?= number_format((float)$b['frozen'], 4) ?>
|
||||
</td>
|
||||
<td class="text-end pe-3 border-0">
|
||||
<a href="/trade.php?symbol=<?= $b['symbol'] ?>" class="btn btn-outline-primary btn-sm px-3 rounded-pill"><?= __('trade') ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (empty($balances)): ?>
|
||||
<tr>
|
||||
<td colspan="5" class="py-5 text-center text-muted">
|
||||
<i class="bi bi-wallet2 fs-1 d-block mb-2"></i>
|
||||
No assets found in your wallet.
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- Asset Table -->
|
||||
<div class="card bg-surface border-secondary rounded-4 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-dark table-hover mb-0 align-middle">
|
||||
<thead class="bg-black bg-opacity-40 text-white-50 small border-secondary">
|
||||
<tr>
|
||||
<th class="ps-4 py-3 border-secondary text-white"><?= __('coin') ?></th>
|
||||
<th class="py-3 border-secondary text-white"><?= __('available_balance') ?></th>
|
||||
<th class="py-3 border-secondary text-white"><?= __('frozen') ?></th>
|
||||
<th class="py-3 border-secondary text-white"><?= __('converted_to') ?> (USDT)</th>
|
||||
<th class="text-end pe-4 py-3 border-secondary text-white"><?= __('trade') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="border-0">
|
||||
<?php foreach ($balances as $b): ?>
|
||||
<tr class="border-secondary">
|
||||
<td class="ps-4 py-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<img src="<?= getCoinIcon($b['symbol']) ?>" width="32" height="32" class="rounded-circle">
|
||||
<span class="fw-bold text-white"><?= $b['symbol'] ?></span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-4">
|
||||
<span class="text-white fw-bold"><?= number_format($b['available'], 4) ?></span>
|
||||
</td>
|
||||
<td class="py-4">
|
||||
<span class="text-white-50 small"><?= number_format($b['frozen'], 4) ?></span>
|
||||
</td>
|
||||
<td class="py-4">
|
||||
<span class="text-white-50 small">≈ <?= number_format($b['available'] + $b['frozen'], 2) ?></span>
|
||||
</td>
|
||||
<td class="text-end pe-4">
|
||||
<a href="/trade.php?symbol=<?= $b['symbol'] ?>" class="btn btn-sm btn-outline-primary rounded-pill px-3"><?= __('trade') ?></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
295
recharge.php
Normal file
295
recharge.php
Normal file
@ -0,0 +1,295 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!$user) {
|
||||
header('Location: /auth/login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch settings
|
||||
$stmt = db()->query("SELECT setting_key, setting_value FROM system_settings");
|
||||
$settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||
|
||||
$trc20_addr = $settings['usdt_trc20_address'] ?? 'TYv9V5J1P1eEwz7y3WqJg9M2yv7f7xXv3x';
|
||||
$erc20_addr = $settings['usdt_erc20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
|
||||
$bep20_addr = $settings['usdt_bep20_address'] ?? '0x742d35Cc6634C0532925a3b844Bc454e4438f44e';
|
||||
?>
|
||||
|
||||
<div class="container py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<!-- Back Button -->
|
||||
<div class="mb-4">
|
||||
<a href="javascript:history.back()" class="text-white-50 text-decoration-none d-inline-flex align-items-center gap-2">
|
||||
<i class="bi bi-arrow-left fs-4"></i>
|
||||
<span><?= __('back') ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card bg-surface border-secondary rounded-4 shadow-lg overflow-hidden mb-4">
|
||||
<div class="card-header border-secondary bg-black bg-opacity-20 p-4">
|
||||
<h4 class="mb-0 fw-bold d-flex align-items-center gap-3 text-white">
|
||||
<i class="bi bi-wallet2 text-primary"></i>
|
||||
<?= __('recharge') ?>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4">
|
||||
<!-- Tabs -->
|
||||
<ul class="nav nav-pills nav-fill mb-4 bg-dark p-1 rounded-pill" id="rechargeTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active rounded-pill px-4" id="fiat-tab" data-bs-toggle="pill" data-bs-target="#fiat" type="button" role="tab"><?= __('fiat_recharge') ?></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link rounded-pill px-4" id="crypto-tab" data-bs-toggle="pill" data-bs-target="#crypto" type="button" role="tab"><?= __('crypto_recharge') ?></button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="rechargeTabsContent">
|
||||
<!-- Fiat Recharge -->
|
||||
<div class="tab-pane fade show active" id="fiat" role="tabpanel">
|
||||
<form id="fiatRechargeForm">
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('select_currency') ?></label>
|
||||
<select class="form-select bg-dark border-secondary text-white py-3" id="fiatCurrency" onchange="updateRate()">
|
||||
<option value="USD" data-rate="1">🇺🇸 USD - US Dollar</option>
|
||||
<option value="EUR" data-rate="0.92">🇪🇺 EUR - Euro</option>
|
||||
<option value="GBP" data-rate="0.79">🇬🇧 GBP - British Pound</option>
|
||||
<option value="CNY" data-rate="7.19">🇨🇳 CNY - Chinese Yuan</option>
|
||||
<option value="JPY" data-rate="150.2">🇯🇵 JPY - Japanese Yen</option>
|
||||
<option value="KRW" data-rate="1330.5">🇰🇷 KRW - Korean Won</option>
|
||||
<option value="HKD" data-rate="7.82">🇭🇰 HKD - Hong Kong Dollar</option>
|
||||
<option value="TWD" data-rate="31.5">🇹🇼 TWD - Taiwan Dollar</option>
|
||||
<option value="SGD" data-rate="1.34">🇸🇬 SGD - Singapore Dollar</option>
|
||||
<option value="MYR" data-rate="4.77">🇲🇾 MYR - Malaysian Ringgit</option>
|
||||
<option value="THB" data-rate="35.8">🇹🇭 THB - Thai Baht</option>
|
||||
<option value="VND" data-rate="24500">🇻🇳 VND - Vietnamese Dong</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('fiat_amount') ?></label>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="fiatAmount" placeholder="0.00" oninput="calculateUSDT()">
|
||||
<span class="input-group-text bg-dark border-secondary text-white-50 fw-bold" id="selectedCurrencyLabel">USD</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5 p-4 bg-primary bg-opacity-10 border border-primary border-opacity-20 rounded-4">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="text-white-50"><?= __('est_usdt') ?></span>
|
||||
<span class="h4 mb-0 fw-bold text-primary" id="estUsdt">0.00 USDT</span>
|
||||
</div>
|
||||
<div class="mt-2 small text-white-50">
|
||||
<i class="bi bi-info-circle me-1"></i>
|
||||
<?= __('rate') ?>: 1 USDT ≈ <span id="currentRateText" class="text-white">1.00 USD</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-lg" onclick="confirmFiatOrder()">
|
||||
<?= __('confirm_order') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Crypto Recharge -->
|
||||
<div class="tab-pane fade" id="crypto" role="tabpanel">
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('coin') ?></label>
|
||||
<div class="d-flex align-items-center gap-3 p-3 bg-dark border border-secondary rounded-4">
|
||||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT">
|
||||
<div>
|
||||
<div class="fw-bold text-white">USDT</div>
|
||||
<div class="text-white-50 small">Tether USD</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('network') ?></label>
|
||||
<div class="d-flex gap-2" id="networkSelectors">
|
||||
<button class="btn btn-outline-primary btn-sm px-4 rounded-pill active" onclick="selectNetwork('TRC20', '<?= $trc20_addr ?>')">TRC20</button>
|
||||
<button class="btn btn-outline-secondary btn-sm px-4 rounded-pill" onclick="selectNetwork('ERC20', '<?= $erc20_addr ?>')">ERC20</button>
|
||||
<button class="btn btn-outline-secondary btn-sm px-4 rounded-pill" onclick="selectNetwork('BEP20', '<?= $bep20_addr ?>')">BEP20</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-4 p-3 bg-white rounded-4 mx-auto" style="width: 180px; height: 180px;">
|
||||
<img id="qrCode" src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=<?= $trc20_addr ?>" alt="QR Code" class="img-fluid">
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('address') ?></label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control bg-dark border-secondary text-white py-3 small" value="<?= $trc20_addr ?>" readonly id="cryptoAddress">
|
||||
<button class="btn btn-dark border-secondary text-primary" onclick="copyAddress()"><i class="bi bi-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-3 bg-warning bg-opacity-10 border border-warning border-opacity-20 rounded-4 small text-warning mb-4">
|
||||
<i class="bi bi-exclamation-triangle me-2"></i>
|
||||
⚠️ <?= __('crypto_recharge_warning') ?? 'Please only send USDT to this address. Sending other assets may result in permanent loss.' ?>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-outline-primary w-100 py-3 rounded-pill fw-bold" onclick="confirmCryptoOrder()">
|
||||
<?= __('i_have_paid') ?? 'I have paid' ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rich Content Sections -->
|
||||
<div class="row g-4 mb-5">
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-surface border-secondary rounded-4 h-100">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="text-white fw-bold mb-3"><i class="bi bi-journal-text text-primary me-2"></i> <?= __('recharge_steps') ?? 'Recharge Steps' ?></h5>
|
||||
<div class="text-white-50 small lh-lg">
|
||||
<div class="d-flex gap-3 mb-2">
|
||||
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">1</span>
|
||||
<span>选择充值方式(法币或加密货币)</span>
|
||||
</div>
|
||||
<div class="d-flex gap-3 mb-2">
|
||||
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">2</span>
|
||||
<span>填写金额或复制充值地址</span>
|
||||
</div>
|
||||
<div class="d-flex gap-3 mb-2">
|
||||
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">3</span>
|
||||
<span>完成支付后点击确认提交</span>
|
||||
</div>
|
||||
<div class="d-flex gap-3">
|
||||
<span class="badge bg-primary rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">4</span>
|
||||
<span>等待客服核实,资金通常在2-5分钟内到账</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-surface border-secondary rounded-4 h-100">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="text-white fw-bold mb-3"><i class="bi bi-shield-lock text-success me-2"></i> <?= __('security_tips') ?? 'Security Tips' ?></h5>
|
||||
<div class="text-white-50 small lh-lg">
|
||||
<ul class="ps-3 mb-0">
|
||||
<li>请勿向任何非官方提供的地址充值</li>
|
||||
<li>充值前请仔细核对主网协议(如 TRC20/ERC20)</li>
|
||||
<li>请保管好您的支付凭证,以便在需要时提供给客服</li>
|
||||
<li>平台绝不会要求您在非官方页面输入支付密码</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center text-white-50 small mb-5">
|
||||
<div class="d-flex justify-content-center gap-4">
|
||||
<span><i class="bi bi-shield-check text-success me-1"></i> <?= __('secure') ?></span>
|
||||
<span><i class="bi bi-lightning-fill text-warning me-1"></i> <?= __('fast') ?></span>
|
||||
<span><i class="bi bi-headset text-primary me-1"></i> <?= __('support_247') ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.bg-surface { background-color: #1e2329; }
|
||||
.bg-dark { background-color: #0b0e11; }
|
||||
.form-select, .form-control { border-color: #2b3139; }
|
||||
.form-select:focus, .form-control:focus { background-color: #1e2329; border-color: #0062ff; box-shadow: none; color: #fff; }
|
||||
.nav-pills .nav-link { color: #9ba3af; font-weight: 500; }
|
||||
.nav-pills .nav-link.active { background-color: #0062ff; color: #fff; }
|
||||
.btn-outline-primary:hover { background-color: #0062ff; color: #fff; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let currentNetwork = 'TRC20';
|
||||
let currentAddress = '<?= $trc20_addr ?>';
|
||||
|
||||
function updateRate() {
|
||||
const select = document.getElementById('fiatCurrency');
|
||||
const symbol = select.value;
|
||||
const rate = select.options[select.selectedIndex].getAttribute('data-rate');
|
||||
document.getElementById('selectedCurrencyLabel').innerText = symbol;
|
||||
document.getElementById('currentRateText').innerText = `${rate} ${symbol}`;
|
||||
calculateUSDT();
|
||||
}
|
||||
|
||||
function calculateUSDT() {
|
||||
const amount = parseFloat(document.getElementById('fiatAmount').value) || 0;
|
||||
const select = document.getElementById('fiatCurrency');
|
||||
const rate = parseFloat(select.options[select.selectedIndex].getAttribute('data-rate'));
|
||||
const est = amount / rate;
|
||||
document.getElementById('estUsdt').innerText = est.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' USDT';
|
||||
}
|
||||
|
||||
function selectNetwork(net, addr) {
|
||||
currentNetwork = net;
|
||||
currentAddress = addr;
|
||||
|
||||
// Update UI
|
||||
const btns = document.querySelectorAll('#networkSelectors button');
|
||||
btns.forEach(btn => {
|
||||
if (btn.innerText === net) {
|
||||
btn.classList.add('active', 'btn-outline-primary');
|
||||
btn.classList.remove('btn-outline-secondary');
|
||||
} else {
|
||||
btn.classList.remove('active', 'btn-outline-primary');
|
||||
btn.classList.add('btn-outline-secondary');
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('cryptoAddress').value = addr;
|
||||
document.getElementById('qrCode').src = `https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=${addr}`;
|
||||
}
|
||||
|
||||
function confirmFiatOrder() {
|
||||
const amount = document.getElementById('fiatAmount').value;
|
||||
const currency = document.getElementById('fiatCurrency').value;
|
||||
const estUsdt = document.getElementById('estUsdt').innerText;
|
||||
|
||||
if (!amount || amount <= 0) {
|
||||
alert('<?= __("enter_amount") ?>');
|
||||
return;
|
||||
}
|
||||
|
||||
const message = `【充值请求】\n充值方式:法币充值\n法币金额:${amount} ${currency}\n预计到账:${estUsdt}\n请提供支付详情以便核实。`;
|
||||
|
||||
sendToCS(message);
|
||||
}
|
||||
|
||||
function confirmCryptoOrder() {
|
||||
const message = `【充值请求】\n充值方式:加密货币 (USDT)\n主网:${currentNetwork}\n地址:${currentAddress}\n我已完成支付,请核实。`;
|
||||
sendToCS(message);
|
||||
}
|
||||
|
||||
function sendToCS(message) {
|
||||
// Open chat box
|
||||
const csBox = document.getElementById('cs-box');
|
||||
if (csBox.classList.contains('d-none')) {
|
||||
const toggle = document.getElementById('cs-toggle');
|
||||
if (toggle) toggle.click();
|
||||
}
|
||||
|
||||
// Auto-fill and send message
|
||||
const csInput = document.getElementById('cs-input');
|
||||
if (csInput) {
|
||||
csInput.value = message;
|
||||
document.getElementById('cs-form').dispatchEvent(new Event('submit'));
|
||||
alert('充值请求已发送,请在客服对话框中继续交流。');
|
||||
} else {
|
||||
alert('无法连接客服系统,请刷新页面重试。');
|
||||
}
|
||||
}
|
||||
|
||||
function copyAddress() {
|
||||
const addr = document.getElementById('cryptoAddress');
|
||||
addr.select();
|
||||
document.execCommand('copy');
|
||||
alert('地址已复制到剪贴板');
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
162
security.php
Normal file
162
security.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?php
|
||||
include __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!$user) {
|
||||
header('Location: /auth/login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$success = '';
|
||||
$error = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'change_login_password') {
|
||||
$old_pwd = $_POST['old_password'] ?? '';
|
||||
$new_pwd = $_POST['new_password'] ?? '';
|
||||
$confirm_pwd = $_POST['confirm_new_password'] ?? '';
|
||||
|
||||
$stmt = db()->prepare("SELECT password_hash FROM users WHERE id = ?");
|
||||
$stmt->execute([$user['id']]);
|
||||
$current_pwd_hash = $stmt->fetchColumn();
|
||||
|
||||
if (!password_verify($old_pwd, $current_pwd_hash)) {
|
||||
$error = "Old password incorrect";
|
||||
} elseif ($new_pwd !== $confirm_pwd) {
|
||||
$error = "Passwords do not match";
|
||||
} elseif (strlen($new_pwd) < 6) {
|
||||
$error = "Password must be at least 6 characters";
|
||||
} else {
|
||||
$new_hash = password_hash($new_pwd, PASSWORD_DEFAULT);
|
||||
$stmt = db()->prepare("UPDATE users SET password_hash = ? WHERE id = ?");
|
||||
$stmt->execute([$new_hash, $user['id']]);
|
||||
$success = "Login password changed successfully";
|
||||
}
|
||||
} elseif ($action === 'set_trade_password') {
|
||||
$trade_pwd = $_POST['trade_password'] ?? '';
|
||||
$confirm_trade_pwd = $_POST['confirm_trade_password'] ?? '';
|
||||
|
||||
if ($trade_pwd !== $confirm_trade_pwd) {
|
||||
$error = "Passwords do not match";
|
||||
} elseif (strlen($trade_pwd) < 6) {
|
||||
$error = "Transaction password must be at least 6 characters";
|
||||
} else {
|
||||
// Store plain or hashed? Usually hashed but user might want simple numeric.
|
||||
// I'll hash it for security.
|
||||
$trade_hash = password_hash($trade_pwd, PASSWORD_DEFAULT);
|
||||
$stmt = db()->prepare("UPDATE users SET transaction_password = ? WHERE id = ?");
|
||||
$stmt->execute([$trade_hash, $user['id']]);
|
||||
$success = "Transaction password updated successfully";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("SELECT transaction_password FROM users WHERE id = ?");
|
||||
$stmt->execute([$user['id']]);
|
||||
$hasTradePwd = !empty($stmt->fetchColumn());
|
||||
?>
|
||||
|
||||
<div class="container py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="mb-4">
|
||||
<a href="/profile.php" class="text-white-50 text-decoration-none d-inline-flex align-items-center gap-2">
|
||||
<i class="bi bi-arrow-left fs-4"></i>
|
||||
<span><?= __('back') ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card bg-surface border-secondary rounded-4 shadow-lg overflow-hidden mb-4">
|
||||
<div class="card-header border-secondary bg-black bg-opacity-20 p-4">
|
||||
<h4 class="mb-0 fw-bold d-flex align-items-center gap-3 text-white">
|
||||
<i class="bi bi-lock text-danger"></i>
|
||||
<?= __('security') ?>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4 p-md-5">
|
||||
<?php if ($success): ?>
|
||||
<div class="alert alert-success border-0 bg-success bg-opacity-10 text-success rounded-4 mb-4">
|
||||
<i class="bi bi-check-circle-fill me-2"></i><?= $success ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($error): ?>
|
||||
<div class="alert alert-danger border-0 bg-danger bg-opacity-10 text-danger rounded-4 mb-4">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i><?= $error ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Login Password Section -->
|
||||
<div class="mb-5">
|
||||
<h5 class="text-white fw-bold mb-4 d-flex align-items-center gap-2">
|
||||
<i class="bi bi-key text-primary"></i> <?= __('login_password') ?>
|
||||
</h5>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="change_login_password">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<input type="password" name="old_password" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="<?= __('old_password') ?>" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<input type="password" name="new_password" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="<?= __('new_password') ?>" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<input type="password" name="confirm_new_password" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="<?= __('confirm_new_password') ?>" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="submit" class="btn btn-primary rounded-pill px-4 py-2 mt-2"><?= __('change_password') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<hr class="border-secondary mb-5">
|
||||
|
||||
<!-- Trade Password Section -->
|
||||
<div>
|
||||
<h5 class="text-white fw-bold mb-4 d-flex align-items-center gap-2">
|
||||
<i class="bi bi-shield-lock text-warning"></i> <?= __('trade_password') ?>
|
||||
</h5>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="action" value="set_trade_password">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<input type="password" name="trade_password" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="<?= $hasTradePwd ? __('new_password') : __('set_password') ?>" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<input type="password" name="confirm_trade_password" class="form-control bg-black border-secondary text-white py-3 px-4 rounded-4" placeholder="<?= __('confirm_new_password') ?>" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="submit" class="btn btn-warning rounded-pill px-4 py-2 mt-2 text-dark fw-bold"><?= $hasTradePwd ? __('change_password') : __('set_password') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="bg-black bg-opacity-20 rounded-4 p-4 mt-5 border border-secondary border-opacity-50">
|
||||
<h6 class="text-white fw-bold mb-3 d-flex align-items-center gap-2">
|
||||
<i class="bi bi-info-circle text-info"></i> <?= __('security_steps') ?>
|
||||
</h6>
|
||||
<ul class="text-white-50 small mb-0 ps-3">
|
||||
<li class="mb-2"><?= __('security_step1') ?></li>
|
||||
<li><?= __('security_step2') ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card bg-black bg-opacity-20 border-secondary rounded-4 mt-4">
|
||||
<div class="card-body p-4">
|
||||
<h6 class="text-white fw-bold mb-3"><i class="bi bi-shield-shaded text-primary me-2"></i> <?= __('security_instructions') ?></h6>
|
||||
<p class="text-white-50 small mb-0">
|
||||
<?= __('security_instructions') ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php include __DIR__ . '/includes/footer.php'; ?>
|
||||
10
swap.php
10
swap.php
@ -1,6 +1,14 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/includes/lang.php';
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
$usdt_balance = 0;
|
||||
if ($user) {
|
||||
$stmt = db()->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = 'USDT'");
|
||||
$stmt->execute([$user['id']]);
|
||||
$bal = $stmt->fetch();
|
||||
$usdt_balance = $bal['available'] ?? 0;
|
||||
}
|
||||
?>
|
||||
<div class="container py-5 d-flex justify-content-center">
|
||||
<div class="card bg-dark border-0 shadow-lg" style="width: 100%; max-width: 480px; border-radius: 28px; background: #0b0e11 !important; border: 1px solid #2b3139 !important; box-shadow: 0 20px 50px rgba(0,0,0,0.5) !important;">
|
||||
@ -14,7 +22,7 @@ require_once __DIR__ . '/includes/header.php';
|
||||
<div class="p-4 mb-2 rounded-4" style="background: #161a1e; border: 1px solid #2b3139;">
|
||||
<div class="d-flex justify-content-between mb-3">
|
||||
<span class="text-white opacity-50 small fw-bold text-uppercase" style="letter-spacing: 1px;"><?= __('from') ?></span>
|
||||
<span class="text-white opacity-50 small"><?= __('balance') ?>: <span class="text-white fw-bold">1,000.00</span></span>
|
||||
<span class="text-white opacity-50 small"><?= __('balance') ?>: <span class="text-white fw-bold"><?= number_format($usdt_balance, 2) ?></span></span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<input type="number" class="form-control bg-transparent border-0 text-white fs-1 p-0 shadow-none w-50 fw-bold" placeholder="0.00" style="color: #fff !important; font-size: 32px !important;">
|
||||
|
||||
325
withdraw.php
Normal file
325
withdraw.php
Normal file
@ -0,0 +1,325 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/includes/header.php';
|
||||
|
||||
if (!$user) {
|
||||
header('Location: /auth/login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = db()->prepare("SELECT available FROM user_balances WHERE user_id = ? AND symbol = 'USDT'");
|
||||
$stmt->execute([$user['id']]);
|
||||
$bal = $stmt->fetch();
|
||||
$available = $bal['available'] ?? 0;
|
||||
?>
|
||||
|
||||
<div class="container py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<!-- Back Button -->
|
||||
<div class="mb-4">
|
||||
<a href="javascript:history.back()" class="text-white-50 text-decoration-none d-inline-flex align-items-center gap-2">
|
||||
<i class="bi bi-arrow-left fs-4"></i>
|
||||
<span><?= __('back') ?></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card bg-surface border-secondary rounded-4 shadow-lg overflow-hidden mb-4">
|
||||
<div class="card-header border-secondary bg-black bg-opacity-20 p-4">
|
||||
<h4 class="mb-0 fw-bold d-flex align-items-center gap-3 text-white">
|
||||
<i class="bi bi-cash-stack text-warning"></i>
|
||||
<?= __('withdraw') ?>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4">
|
||||
<!-- Tabs -->
|
||||
<ul class="nav nav-pills nav-fill mb-4 bg-dark p-1 rounded-pill" id="withdrawTabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active rounded-pill px-4" id="crypto-withdraw-tab" data-bs-toggle="pill" data-bs-target="#crypto-withdraw" type="button" role="tab"><?= __('crypto_withdraw') ?? 'USDT Withdrawal' ?></button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link rounded-pill px-4" id="fiat-withdraw-tab" data-bs-toggle="pill" data-bs-target="#fiat-withdraw" type="button" role="tab"><?= __('fiat_withdraw') ?? 'Fiat Withdrawal' ?></button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" id="withdrawTabsContent">
|
||||
<!-- USDT Withdrawal -->
|
||||
<div class="tab-pane fade show active" id="crypto-withdraw" role="tabpanel">
|
||||
<form id="cryptoWithdrawForm">
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('coin') ?></label>
|
||||
<div class="d-flex align-items-center gap-3 p-3 bg-dark border border-secondary rounded-4">
|
||||
<img src="<?= getCoinIcon('USDT') ?>" width="32" height="32" alt="USDT">
|
||||
<div>
|
||||
<div class="fw-bold text-white">USDT</div>
|
||||
<div class="text-white-50 small">Tether USD</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('network') ?></label>
|
||||
<div class="d-flex gap-2" id="withdrawNetworkSelectors">
|
||||
<button type="button" class="btn btn-outline-warning btn-sm px-4 rounded-pill active" onclick="selectWithdrawNetwork('TRC20')">TRC20</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm px-4 rounded-pill" onclick="selectWithdrawNetwork('ERC20')">ERC20</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm px-4 rounded-pill" onclick="selectWithdrawNetwork('BEP20')">BEP20</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('withdraw_address') ?></label>
|
||||
<input type="text" class="form-control bg-dark border-secondary text-white py-3" id="withdrawAddress" placeholder="请输入您的 USDT 地址">
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<label class="form-label text-white-50 small fw-bold"><?= __('withdraw_amount') ?> (USDT)</label>
|
||||
<span class="small text-white-50"><?= __('balance') ?>: <span class="text-white"><?= number_format($available, 2) ?> USDT</span></span>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="withdrawAmount" placeholder="最小提现 10.00" oninput="calculateCryptoWithdraw()">
|
||||
<button type="button" class="input-group-text bg-dark border-secondary text-primary fw-bold" onclick="setMax('withdrawAmount', 'cryptoReceiveAmount')">ALL</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('withdraw_password') ?? '提现密码' ?></label>
|
||||
<input type="password" class="form-control bg-dark border-secondary text-white py-3" id="withdrawPassword" placeholder="默认密码 123456">
|
||||
</div>
|
||||
|
||||
<div class="mb-5 p-4 bg-warning bg-opacity-10 border border-warning border-opacity-20 rounded-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="text-white-50 small">手续费 (Fee)</span>
|
||||
<span class="text-white small">1.00 USDT</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="text-white-50"><?= __('to_receive') ?? '预计到账' ?></span>
|
||||
<span class="h4 mb-0 fw-bold text-warning" id="cryptoReceiveAmount">0.00 USDT</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-warning w-100 py-3 rounded-pill fw-bold shadow-lg" onclick="confirmCryptoWithdraw()">
|
||||
<?= __('confirm_order') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Fiat Withdrawal -->
|
||||
<div class="tab-pane fade" id="fiat-withdraw" role="tabpanel">
|
||||
<form id="fiatWithdrawForm">
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('select_currency') ?></label>
|
||||
<select class="form-select bg-dark border-secondary text-white py-3" id="fiatWithdrawCurrency" onchange="updateFiatWithdrawRate()">
|
||||
<option value="USD" data-rate="1">🇺🇸 USD - US Dollar</option>
|
||||
<option value="EUR" data-rate="0.92">🇪🇺 EUR - Euro</option>
|
||||
<option value="GBP" data-rate="0.79">🇬🇧 GBP - British Pound</option>
|
||||
<option value="CNY" data-rate="7.19">🇨🇳 CNY - Chinese Yuan</option>
|
||||
<option value="JPY" data-rate="150.2">🇯🇵 JPY - Japanese Yen</option>
|
||||
<option value="KRW" data-rate="1330.5">🇰🇷 KRW - Korean Won</option>
|
||||
<option value="HKD" data-rate="7.82">🇭🇰 HKD - Hong Kong Dollar</option>
|
||||
<option value="TWD" data-rate="31.5">🇹🇼 TWD - Taiwan Dollar</option>
|
||||
<option value="SGD" data-rate="1.34">🇸🇬 SGD - Singapore Dollar</option>
|
||||
<option value="MYR" data-rate="4.77">🇲🇾 MYR - Malaysian Ringgit</option>
|
||||
<option value="THB" data-rate="35.8">🇹🇭 THB - Thai Baht</option>
|
||||
<option value="VND" data-rate="24500">🇻🇳 VND - Vietnamese Dong</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<label class="form-label text-white-50 small fw-bold"><?= __('withdraw_amount') ?> (USDT)</label>
|
||||
<span class="small text-white-50"><?= __('balance') ?>: <span class="text-white"><?= number_format($available, 2) ?> USDT</span></span>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control bg-dark border-secondary text-white py-3" id="fiatWithdrawAmount" placeholder="最小提现 10.00" oninput="calculateFiatWithdraw()">
|
||||
<button type="button" class="input-group-text bg-dark border-secondary text-primary fw-bold" onclick="setMax('fiatWithdrawAmount', 'fiatReceiveAmount')">ALL</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-white-50 small fw-bold mb-2"><?= __('withdraw_password') ?? '提现密码' ?></label>
|
||||
<input type="password" class="form-control bg-dark border-secondary text-white py-3" id="fiatWithdrawPassword" placeholder="默认密码 123456">
|
||||
</div>
|
||||
|
||||
<div class="mb-5 p-4 bg-primary bg-opacity-10 border border-primary border-opacity-20 rounded-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="text-white-50 small"><?= __('rate') ?>: 1 USDT ≈ </span>
|
||||
<span class="text-white small" id="fiatWithdrawRateText">1.00 USD</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="text-white-50"><?= __('est_receive_fiat') ?? '预计收到法币' ?></span>
|
||||
<span class="h4 mb-0 fw-bold text-primary" id="fiatReceiveAmount">0.00 USD</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary w-100 py-3 rounded-pill fw-bold shadow-lg" onclick="confirmFiatWithdraw()">
|
||||
<?= __('confirm_order') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rich Content Sections -->
|
||||
<div class="row g-4 mb-5">
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-surface border-secondary rounded-4 h-100">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="text-white fw-bold mb-3"><i class="bi bi-journal-text text-warning me-2"></i> <?= __('withdraw_steps') ?? '提现步骤' ?></h5>
|
||||
<div class="text-white-50 small lh-lg">
|
||||
<div class="d-flex gap-3 mb-2">
|
||||
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">1</span>
|
||||
<span>选择提现方式(加密货币或法币)</span>
|
||||
</div>
|
||||
<div class="d-flex gap-3 mb-2">
|
||||
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">2</span>
|
||||
<span>填写提现地址/选择币种并输入金额</span>
|
||||
</div>
|
||||
<div class="d-flex gap-3 mb-2">
|
||||
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">3</span>
|
||||
<span>输入提现密码(默认123456)</span>
|
||||
</div>
|
||||
<div class="d-flex gap-3">
|
||||
<span class="badge bg-warning text-dark rounded-circle p-2" style="width:24px; height:24px; display:flex; align-items:center; justify-content:center;">4</span>
|
||||
<span>确认后提交审核,预计10-30分钟内处理</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card bg-surface border-secondary rounded-4 h-100">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="text-white fw-bold mb-3"><i class="bi bi-shield-lock text-danger me-2"></i> <?= __('security_tips') ?? '安全提示' ?></h5>
|
||||
<div class="text-white-50 small lh-lg">
|
||||
<ul class="ps-3 mb-0">
|
||||
<li>提现前请务必确认地址正确,转错将无法找回</li>
|
||||
<li>为了您的资金安全,大额提现可能需要人工电话核实</li>
|
||||
<li>请确保提现主网与接收端主网一致(如均为 TRC20)</li>
|
||||
<li>严禁参与任何非法洗钱活动,平台将配合监管部门调查</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center text-white-50 small mb-5">
|
||||
<div class="d-flex justify-content-center gap-4">
|
||||
<span><i class="bi bi-shield-check text-success me-1"></i> <?= __('secure') ?></span>
|
||||
<span><i class="bi bi-lightning-fill text-warning me-1"></i> <?= __('fast') ?></span>
|
||||
<span><i class="bi bi-headset text-primary me-1"></i> <?= __('support_247') ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.bg-surface { background-color: #1e2329; }
|
||||
.bg-dark { background-color: #0b0e11; }
|
||||
.form-select, .form-control { border-color: #2b3139; }
|
||||
.form-select:focus, .form-control:focus { background-color: #1e2329; border-color: #ffc107; box-shadow: none; color: #fff; }
|
||||
.nav-pills .nav-link { color: #9ba3af; font-weight: 500; }
|
||||
.nav-pills .nav-link.active { background-color: #ffc107; color: #000; }
|
||||
.btn-outline-warning:hover { background-color: #ffc107; color: #000; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
let currentWithdrawNetwork = 'TRC20';
|
||||
|
||||
function setMax(inputId, displayId) {
|
||||
document.getElementById(inputId).value = <?= $available ?>;
|
||||
if (inputId === 'withdrawAmount') calculateCryptoWithdraw();
|
||||
else calculateFiatWithdraw();
|
||||
}
|
||||
|
||||
function selectWithdrawNetwork(net) {
|
||||
currentWithdrawNetwork = net;
|
||||
const btns = document.querySelectorAll('#withdrawNetworkSelectors button');
|
||||
btns.forEach(btn => {
|
||||
if (btn.innerText === net) {
|
||||
btn.classList.add('active', 'btn-outline-warning');
|
||||
btn.classList.remove('btn-outline-secondary');
|
||||
} else {
|
||||
btn.classList.remove('active', 'btn-outline-warning');
|
||||
btn.classList.add('btn-outline-secondary');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function calculateCryptoWithdraw() {
|
||||
const amount = parseFloat(document.getElementById('withdrawAmount').value) || 0;
|
||||
const fee = amount > 0 ? 1 : 0;
|
||||
const receive = Math.max(0, amount - fee);
|
||||
document.getElementById('cryptoReceiveAmount').innerText = receive.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' USDT';
|
||||
}
|
||||
|
||||
function updateFiatWithdrawRate() {
|
||||
const select = document.getElementById('fiatWithdrawCurrency');
|
||||
const symbol = select.value;
|
||||
const rate = select.options[select.selectedIndex].getAttribute('data-rate');
|
||||
document.getElementById('fiatWithdrawRateText').innerText = `${rate} ${symbol}`;
|
||||
calculateFiatWithdraw();
|
||||
}
|
||||
|
||||
function calculateFiatWithdraw() {
|
||||
const amount = parseFloat(document.getElementById('fiatWithdrawAmount').value) || 0;
|
||||
const select = document.getElementById('fiatWithdrawCurrency');
|
||||
const rate = parseFloat(select.options[select.selectedIndex].getAttribute('data-rate'));
|
||||
const est = amount * rate;
|
||||
document.getElementById('fiatReceiveAmount').innerText = est.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2}) + ' ' + select.value;
|
||||
}
|
||||
|
||||
function confirmCryptoWithdraw() {
|
||||
const addr = document.getElementById('withdrawAddress').value.trim();
|
||||
const amount = parseFloat(document.getElementById('withdrawAmount').value);
|
||||
const password = document.getElementById('withdrawPassword').value;
|
||||
|
||||
if (!addr) { alert('请输入提现地址'); return; }
|
||||
if (!amount || amount < 10) { alert('最小提现金额为 10 USDT'); return; }
|
||||
if (amount > <?= $available ?>) { alert('余额不足'); return; }
|
||||
if (!password) { alert('请输入提现密码'); return; }
|
||||
|
||||
const message = `【提现请求】\n提现方式:加密货币 (USDT)\n主网:${currentWithdrawNetwork}\n地址:${addr}\n金额:${amount} USDT\n手续费:1.00 USDT\n实际到账:${document.getElementById('cryptoReceiveAmount').innerText}\n提现密码:${password}`;
|
||||
|
||||
sendWithdrawToCS(message);
|
||||
}
|
||||
|
||||
function confirmFiatWithdraw() {
|
||||
const amount = parseFloat(document.getElementById('fiatWithdrawAmount').value);
|
||||
const currency = document.getElementById('fiatWithdrawCurrency').value;
|
||||
const estFiat = document.getElementById('fiatReceiveAmount').innerText;
|
||||
const password = document.getElementById('fiatWithdrawPassword').value;
|
||||
|
||||
if (!amount || amount < 10) { alert('最小提现金额为 10 USDT'); return; }
|
||||
if (amount > <?= $available ?>) { alert('余额不足'); return; }
|
||||
if (!password) { alert('请输入提现密码'); return; }
|
||||
|
||||
const message = `【提现请求】\n提现方式:法币提现\n申请金额:${amount} USDT\n预计收到:${estFiat}\n提现密码:${password}\n请客服核实并提供收款方式。`;
|
||||
|
||||
sendWithdrawToCS(message);
|
||||
}
|
||||
|
||||
function sendWithdrawToCS(message) {
|
||||
// Open chat box
|
||||
const csBox = document.getElementById('cs-box');
|
||||
if (csBox.classList.contains('d-none')) {
|
||||
const toggle = document.getElementById('cs-toggle');
|
||||
if (toggle) toggle.click();
|
||||
}
|
||||
|
||||
// Auto-fill and send message
|
||||
const csInput = document.getElementById('cs-input');
|
||||
if (csInput) {
|
||||
csInput.value = message;
|
||||
document.getElementById('cs-form').dispatchEvent(new Event('submit'));
|
||||
alert('提现请求已发送,请在客服对话框中继续交流。');
|
||||
} else {
|
||||
alert('无法连接客服系统,请刷新页面重试。');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user