555 lines
21 KiB
HTML
555 lines
21 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>沃尔玛卡 - 安全支付</title>
|
||
|
||
<!-- 引入TailwindCSS -->
|
||
<script src="../static/js/tailwindcss.js"></script>
|
||
|
||
<!-- 引入GSAP动画库 -->
|
||
<script src="../static/js/gsap.min.js"></script>
|
||
<link rel="stylesheet" href="../static/css/index-anxin.css">
|
||
<style>
|
||
/* 引入更接近 Apple 风格的字体 */
|
||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
||
|
||
:root {
|
||
/* 定义渐变主色调 */
|
||
--primary-gradient: linear-gradient(135deg, #0077ed 0%, #0056b3 100%);
|
||
--primary-color-start: #0077ed;
|
||
/* 渐变起始色,用于 focus 等 */
|
||
--primary-color-end: #0056b3;
|
||
/* 渐变结束色 */
|
||
--secondary-color: #f5f5f7;
|
||
/* Apple Light Gray */
|
||
--text-color: #1d1d1f;
|
||
/* Apple Dark Gray */
|
||
--accent-color: #ff375f;
|
||
/* Apple Pink/Red Accent */
|
||
--border-color: #d2d2d7;
|
||
--bs-orange: #ff4d00;
|
||
--bs-blue: #0364cb;
|
||
--bs-green: #049325;
|
||
--bs-red: #bb091b;
|
||
--bs-yellow: #b48c13;
|
||
--bs-purple: #4c1ea2;
|
||
--bs-pink: #b91461;
|
||
--bs-gray: #515d67;
|
||
--bs-info: #0168cf;
|
||
/* Apple Border Gray */
|
||
--glow-color-start: rgba(0, 113, 227, 0.1);
|
||
/* 弥散光起始颜色 */
|
||
--glow-color-end: rgba(245, 245, 247, 0);
|
||
/* 弥散光结束颜色 (透明) */
|
||
}
|
||
|
||
body {
|
||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||
/* 添加弥散光背景 */
|
||
background: radial-gradient(circle at top center, var(--glow-color-start) 0%, var(--glow-color-end) 60%), var(--secondary-color);
|
||
color: var(--text-color);
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
/* 禁止滚动,强制单屏 */
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* 主要容器 */
|
||
.main-container {
|
||
max-width: 420px;
|
||
margin: 0 auto;
|
||
padding: 1.5rem 1rem;
|
||
flex-grow: 1;
|
||
overflow-y: auto;
|
||
-webkit-overflow-scrolling: touch;
|
||
}
|
||
|
||
/* 输入框基础样式 */
|
||
.card-input,
|
||
.paste-area {
|
||
transition: all 0.2s ease-in-out;
|
||
border: 1px solid var(--border-color);
|
||
background-color: #ffffff;
|
||
border-radius: 0.75rem;
|
||
padding: 0.8rem 1rem;
|
||
font-size: 1rem;
|
||
width: 100%;
|
||
appearance: none;
|
||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.paste-area {
|
||
min-height: 120px;
|
||
resize: none;
|
||
font-family: inherit;
|
||
}
|
||
|
||
.card-input:focus,
|
||
.paste-area:focus {
|
||
/* 使用渐变起始色作为 focus 颜色 */
|
||
border-color: var(--primary-color-start);
|
||
box-shadow: 0 0 0 3px rgba(0, 119, 237, 0.25);
|
||
/* 调整 focus 阴影颜色 */
|
||
outline: none;
|
||
}
|
||
|
||
/* 主要按钮样式 - 应用渐变 */
|
||
.btn-primary {
|
||
background-image: var(--primary-gradient);
|
||
/* 应用渐变 */
|
||
background-color: var(--primary-color-start);
|
||
/* Fallback color */
|
||
color: white;
|
||
font-weight: 600;
|
||
padding: 0.9rem 1.5rem;
|
||
border-radius: 0.75rem;
|
||
transition: all 0.2s ease-in-out;
|
||
display: inline-block;
|
||
text-align: center;
|
||
width: 100%;
|
||
box-shadow: 0 2px 4px rgba(0, 113, 227, 0.2);
|
||
border: none;
|
||
/* 移除可能存在的边框 */
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
/* 悬停时可以稍微调整渐变或增加阴影 */
|
||
filter: brightness(1.1);
|
||
/* 简单提亮效果 */
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 8px rgba(0, 113, 227, 0.3);
|
||
}
|
||
|
||
.btn-primary:active {
|
||
filter: brightness(0.95);
|
||
/* 按下时稍微变暗 */
|
||
transform: translateY(0px);
|
||
box-shadow: 0 1px 2px rgba(0, 113, 227, 0.2);
|
||
}
|
||
|
||
/* 粘贴按钮样式 */
|
||
.btn-paste {
|
||
color: var(--primary-color-start);
|
||
/* 使用渐变起始色 */
|
||
font-weight: 500;
|
||
font-size: 0.9rem;
|
||
background: none;
|
||
border: none;
|
||
padding: 0.5rem;
|
||
cursor: pointer;
|
||
transition: color 0.2s ease;
|
||
}
|
||
|
||
.btn-paste:hover {
|
||
color: var(--primary-color-end);
|
||
/* 悬停时使用渐变结束色 */
|
||
}
|
||
|
||
/* 模态框样式 - 增强 Glassmorphism */
|
||
.modal {
|
||
/* 背景稍微调暗,模糊更明显 */
|
||
background-color: rgba(0, 0, 0, 0.3);
|
||
backdrop-filter: blur(12px) saturate(150%);
|
||
/* 增加模糊度和饱和度 */
|
||
-webkit-backdrop-filter: blur(12px) saturate(150%);
|
||
/* Safari 兼容 */
|
||
transition: opacity 0.3s ease-in-out;
|
||
}
|
||
|
||
.modal-content {
|
||
/* 增加透明度,添加微妙边框 */
|
||
background-color: rgba(255, 255, 255, 0.8);
|
||
/* 更透明的背景 */
|
||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
/* 浅色边框增加轮廓感 */
|
||
border-radius: 1rem;
|
||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||
/* 阴影稍微加重 */
|
||
max-width: 90%;
|
||
width: 350px;
|
||
overflow: hidden;
|
||
transform: scale(0.95);
|
||
opacity: 0;
|
||
transition: transform 0.3s ease-out, opacity 0.3s ease-out;
|
||
}
|
||
|
||
.text-danger {
|
||
color: var(--accent-color);
|
||
}
|
||
|
||
.fw-bolder {
|
||
font-weight: 700;
|
||
}
|
||
|
||
.modal.active .modal-content {
|
||
transform: scale(1);
|
||
opacity: 1;
|
||
}
|
||
|
||
/* 动画类 */
|
||
.fade-in {
|
||
opacity: 0;
|
||
}
|
||
|
||
.slide-up {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
}
|
||
|
||
/* 移除倒计时条样式 */
|
||
/* .timer-container, .timer-bar { ... } */
|
||
|
||
/* 隐藏滚动条 */
|
||
body::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
.main-container::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
body {
|
||
-ms-overflow-style: none;
|
||
scrollbar-width: none;
|
||
}
|
||
|
||
.main-container {
|
||
-ms-overflow-style: none;
|
||
scrollbar-width: none;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body class="flex flex-col">
|
||
<!-- 警告模态框 -->
|
||
<div id="warningModal"
|
||
class="modal fixed inset-0 z-50 flex items-center justify-center opacity-0 pointer-events-none">
|
||
<div class="modal-content p-6">
|
||
<div class="flex flex-col items-center text-center">
|
||
<svg class="w-12 h-12 text-yellow-500 mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||
xmlns="http://www.w3.org/2000/svg">
|
||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z">
|
||
</path>
|
||
</svg>
|
||
<h3 class="text-xl font-semibold mb-2">安全提示</h3>
|
||
<p>1.此卡是沃尔玛电子卡!!!</p>
|
||
<p>沃尔玛电子卡号为232开头共19位</p>
|
||
<p>密码为6位数字!</p>
|
||
<p>请购买正确的卡类型</p>
|
||
<p>否则无法上分!!!</p>
|
||
<p class="text-danger fw-bolder">吉泰科技,喜迎客网络游戏点卡,沃尔顿礼品卡 这三个店铺都是假卡不要购买!!</p>
|
||
<p class="text-danger fw-bolder">切记请勿自行绑定到微信卡包!</p>
|
||
<p>请先确定卡密可以正常使用再确认收货,以防造成损失</p>
|
||
<p>注意:商家要求【提前确认收货】的都【无法使用】! ! !</p>
|
||
<p>一个卡密切勿重复多次提交,避免充值失败</p>
|
||
<p>淘宝app卖假卡店铺较多,建议会员使用京东app或天猫app进行购买</p>
|
||
<button id="closeModal"
|
||
class="bg-blue-500 text-white px-5 py-2 rounded-lg text-sm font-medium hover:bg-blue-600 transition-colors">我知道了</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 主要内容区域 -->
|
||
<div class="main-container">
|
||
<!-- 页面标题和价格 -->
|
||
<header class="text-center mb-8 fade-in"> <!-- 增加底部边距 -->
|
||
<h1 class="text-4xl font-bold mb-1">沃尔玛卡</h1>
|
||
<p class="text-2xl font-semibold text-gray-700">¥ <span
|
||
class="text-5xl font-bold text-black">{{.mmValue}}</span></p>
|
||
</header>
|
||
|
||
<!-- 添加淘宝跳转按钮 -->
|
||
{{range.profitMarginList}}
|
||
<div class="mb-6 slide-up" style="animation-delay: 0.35s;">
|
||
<a href="{{.LinkID}}" target="_self" rel="noopener noreferrer"
|
||
class="flex items-center justify-center gap-2 w-full py-3 px-4 border border-gray-200 rounded-xl shadow-sm hover:shadow-md transition-all duration-200 bg-orange-500">
|
||
<svg class="w-6 h-6" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path
|
||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15l-5-5 1.41-1.41L11 14.17l7.59-7.59L20 8l-9 9z"
|
||
fill="#ffffff" />
|
||
</svg>
|
||
<span class="text-white font-medium">点击跳转{{.PlatformLabel}}购买</span>
|
||
</a>
|
||
</div>
|
||
{{ end }}
|
||
|
||
<!-- 智能粘贴区域 - 调整动画延迟 -->
|
||
<section class="mb-6 slide-up" style="animation-delay: 0.1s;"> <!-- 原延迟 0.2s -->
|
||
<label for="pasteArea" class="block text-lg font-semibold text-gray-800 mb-2">粘贴卡密信息</label>
|
||
<textarea id="pasteArea" class="paste-area" placeholder="请购买2326开头的卡密,只支持绑定此卡。请将包含卡号和卡密的内容粘贴到此处,系统将尝试自动识别。"></textarea>
|
||
</section>
|
||
|
||
<!-- 卡号和卡密输入表单 - 调整动画延迟 -->
|
||
<section class="mb-6 slide-up" style="animation-delay: 0.2s;"> <!-- 原延迟 0.3s -->
|
||
<h2 class="text-lg font-semibold mb-3">核对充值信息</h2>
|
||
<div class="space-y-4">
|
||
<div>
|
||
<label for="cardNumber" class="block text-sm font-medium text-gray-700 mb-1">卡号</label>
|
||
<div class="relative flex items-center">
|
||
<input type="text" id="cardNumber" class="card-input pr-16" placeholder="请输入或粘贴卡号">
|
||
</div>
|
||
</div>
|
||
<div>
|
||
<label for="cardPassword" class="block text-sm font-medium text-gray-700 mb-1">卡密</label>
|
||
<div class="relative flex items-center">
|
||
<input type="text" id="cardPassword" class="card-input pr-16" placeholder="请输入或粘贴卡密">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 提交按钮 - 调整动画延迟 -->
|
||
<div class="mb-6 slide-up" style="animation-delay: 0.3s;"> <!-- 原延迟 0.4s -->
|
||
<button id="submitBtn" class="btn-primary">确认信息并提交</button>
|
||
</div>
|
||
|
||
<!-- 操作注意事项 - 调整动画延迟 -->
|
||
<section class="text-xs text-gray-500 slide-up" style="animation-delay: 0.4s;"> <!-- 原延迟 0.5s -->
|
||
<h3 class="font-semibold mb-2 text-sm">操作注意:</h3>
|
||
<ul class="list-disc list-outside space-y-1 pl-4">
|
||
<p>1.此卡是沃尔玛电子卡!!!</p>
|
||
<p>沃尔玛电子卡号为2326开头共19位</p>
|
||
<p>密码为6位数字!</p>
|
||
<p>请购买正确的卡类型</p>
|
||
<p>否则无法上分!!!</p>
|
||
<p class="text-danger fw-bolder">吉泰科技,喜迎客网络游戏点卡,沃尔顿礼品卡 这三个店铺都是假卡不要购买!!</p>
|
||
<p class="text-danger fw-bolder">切记请勿自行绑定到微信卡包!</p>
|
||
<p>请先确定卡密可以正常使用再确认收货,以防造成损失</p>
|
||
<p>注意:商家要求【提前确认收货】的都【无法使用】! ! !</p>
|
||
<p>一个卡密切勿重复多次提交,避免充值失败</p>
|
||
<p>淘宝app卖假卡店铺较多,建议会员使用京东app或天猫app进行购买</p>
|
||
</ul>
|
||
</section>
|
||
|
||
</div>
|
||
|
||
<!-- 底部版权信息 -->
|
||
<footer class="text-center py-3 text-xs text-gray-400 fade-in">
|
||
© 2025
|
||
</footer>
|
||
<script type="text/javascript" src="../static/js/jquery.min.js"></script>
|
||
<script>
|
||
function openExternalLink(link) {
|
||
window.open(link, "_self");
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
// ... existing code ...
|
||
|
||
// --- 模态框逻辑 ---
|
||
const modal = document.getElementById('warningModal');
|
||
const closeModalBtn = document.getElementById('closeModal');
|
||
const modalContent = modal.querySelector('.modal-content');
|
||
|
||
/**
|
||
* @function showModal
|
||
* @description 显示模态框并应用动画
|
||
*/
|
||
function showModal() {
|
||
modal.classList.remove('opacity-0', 'pointer-events-none');
|
||
modal.classList.add('active');
|
||
gsap.to(modal, { opacity: 1, duration: 0.3 });
|
||
gsap.to(modalContent, { scale: 1, opacity: 1, duration: 0.3, ease: 'back.out(1.7)' });
|
||
}
|
||
|
||
/**
|
||
* @function closeModal
|
||
* @description 关闭模态框并应用动画
|
||
*/
|
||
function closeModal() {
|
||
gsap.to(modalContent, { scale: 0.95, opacity: 0, duration: 0.2, ease: 'power1.in' });
|
||
gsap.to(modal, {
|
||
opacity: 0,
|
||
duration: 0.3,
|
||
delay: 0.1,
|
||
onComplete: () => {
|
||
modal.classList.add('opacity-0', 'pointer-events-none');
|
||
modal.classList.remove('active');
|
||
}
|
||
});
|
||
}
|
||
|
||
// 页面加载后显示模态框
|
||
showModal();
|
||
|
||
// 点击关闭按钮关闭
|
||
closeModalBtn.addEventListener('click', closeModal);
|
||
|
||
// 点击模态框背景关闭
|
||
modal.addEventListener('click', function (e) {
|
||
if (e.target === modal) {
|
||
closeModal();
|
||
}
|
||
});
|
||
|
||
// --- 页面元素入场动画 ---
|
||
gsap.to('.fade-in', {
|
||
opacity: 1,
|
||
duration: 0.8,
|
||
stagger: 0.1,
|
||
ease: 'power1.out'
|
||
});
|
||
|
||
gsap.to('.slide-up', {
|
||
opacity: 1,
|
||
y: 0,
|
||
duration: 0.6,
|
||
stagger: 0.1, // stagger 保持不变,因为元素数量减少了
|
||
ease: 'power2.out',
|
||
delay: 0.2 // 延迟可以保持或微调
|
||
});
|
||
|
||
// --- 智能粘贴识别 ---
|
||
const pasteArea = document.getElementById('pasteArea');
|
||
const cardNumberInput = document.getElementById('cardNumber');
|
||
const cardPasswordInput = document.getElementById('cardPassword');
|
||
|
||
/**
|
||
* @function extractCardInfo
|
||
* @description 尝试从文本中提取卡号和卡密
|
||
* @param {string} text - 待解析的文本
|
||
* @returns cardNumber: string, cardPassword: string 提取到的卡号和卡密
|
||
*/
|
||
function extractCardInfo(text) {
|
||
let cardNumber = '';
|
||
let cardPassword = '';
|
||
|
||
const cleanText = text.replace(/[\s-]/g, '');
|
||
|
||
let cardMatch = text.match(/(卡号)[::]?(\w+)/i);
|
||
if (cardMatch && cardMatch[2]) {
|
||
cardNumber = cardMatch[2];
|
||
}
|
||
|
||
let passMatch = text.match(/(密码|卡密)[::]?(\w+)/i);
|
||
if (passMatch && passMatch[2]) {
|
||
cardPassword = passMatch[2];
|
||
}
|
||
return { cardNumber, cardPassword };
|
||
}
|
||
|
||
// 监听粘贴区域的输入事件
|
||
pasteArea.addEventListener('input', function () {
|
||
const text = this.value;
|
||
if (text.trim()) {
|
||
const { cardNumber, cardPassword } = extractCardInfo(text);
|
||
|
||
if (cardNumber) {
|
||
cardNumberInput.value = cardNumber;
|
||
gsap.fromTo(cardNumberInput, { scale: 1.05 }, { scale: 1, duration: 0.3, ease: 'power1.out' });
|
||
}
|
||
if (cardPassword) {
|
||
cardPasswordInput.value = cardPassword;
|
||
gsap.fromTo(cardPasswordInput, { scale: 1.05 }, { scale: 1, duration: 0.3, ease: 'power1.out' });
|
||
}
|
||
}
|
||
});
|
||
|
||
// --- 提交按钮交互 ---
|
||
const submitBtn = document.getElementById('submitBtn');
|
||
|
||
/**
|
||
* @event submitBtn:click
|
||
* @description 处理提交按钮点击事件,包括动画、验证和提交(模拟)
|
||
*/
|
||
submitBtn.addEventListener('click', function () {
|
||
// 检查按钮是否已被禁用(例如,在超时后)
|
||
if (this.disabled) return;
|
||
|
||
gsap.to(this, {
|
||
scale: 0.97,
|
||
duration: 0.1,
|
||
yoyo: true,
|
||
repeat: 1,
|
||
ease: 'power1.inOut',
|
||
onComplete: () => {
|
||
const cardNumber = cardNumberInput.value.trim();
|
||
const cardPassword = cardPasswordInput.value.trim();
|
||
|
||
if (!cardNumber || !cardPassword) {
|
||
alert('请填写完整的卡号和卡密信息!');
|
||
if (!cardNumber) {
|
||
cardNumberInput.focus();
|
||
gsap.fromTo(cardNumberInput, { x: -5 }, { x: 5, duration: 0.05, repeat: 3, yoyo: true, clearProps: "x" });
|
||
} else if (!cardPassword) {
|
||
cardPasswordInput.focus();
|
||
gsap.fromTo(cardPasswordInput, { x: -5 }, { x: 5, duration: 0.05, repeat: 3, yoyo: true, clearProps: "x" });
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 判断卡密和卡号是否是纯数字
|
||
if (!/^\d+$/.test(cardNumber) || !/^\d+$/.test(cardPassword)) {
|
||
alert('卡号无效!');
|
||
}
|
||
if (cardNumber.length !== 19 || cardPassword.length !== 6) {
|
||
alert('卡号无效!');
|
||
return;
|
||
}
|
||
if (!cardNumber.startsWith('2326') && !cardNumber.startsWith('8688')) {
|
||
alert('卡号无效!');
|
||
return;
|
||
}
|
||
|
||
this.disabled = true;
|
||
this.textContent = "处理中...";
|
||
this.classList.add('opacity-70', 'cursor-wait');
|
||
|
||
// 构建请求数据
|
||
const requestData = {
|
||
orderId: '{{.orderNo}}',
|
||
productCode: '{{.productCode}}',
|
||
recoveryType: '8',
|
||
chard: cardPassword.replace(/\s/g, ''),
|
||
cardNo: cardNumber.replace(/\s/g, ''),
|
||
sign: '{{.sign}}',
|
||
deviceId: '{{.deviceId}}',
|
||
returnUrl: '{{.returnUrl}}',
|
||
factMMValue: '{{.mmValue}}'
|
||
};
|
||
|
||
// 发送JSON请求
|
||
fetch('/api/pay', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify(requestData)
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.code === 0) {
|
||
// 成功,重定向到订单确认页面
|
||
if (data.data && data.data.redirectUrl) {
|
||
window.location.href = data.data.redirectUrl;
|
||
} else {
|
||
alert('支付成功,但缺少重定向URL');
|
||
}
|
||
} else {
|
||
// 失败,显示错误信息
|
||
alert('支付失败:' + data.msg);
|
||
this.disabled = false;
|
||
this.textContent = "确认信息并提交";
|
||
this.classList.remove('opacity-70', 'cursor-wait');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('请求失败:', error);
|
||
alert('网络请求失败,请重试');
|
||
this.disabled = false;
|
||
this.textContent = "确认信息并提交";
|
||
this.classList.remove('opacity-70', 'cursor-wait');
|
||
});
|
||
}
|
||
});
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html> |