市场夺宝奇兵
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

579 lines
27 KiB

9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
9 hours ago
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <meta http-equiv="pragma" content="no-cache">
  8. <meta http-equiv="cache-control" content="no-cache">
  9. <meta http-equiv="expires" content="0">
  10. <link rel="shortcut icon" href="dbqb_favicon.ico" />
  11. <link rel="Bookmark" href="dbqb_favicon.ico" />
  12. <meta http-equiv="keywords" content="夺宝奇兵,homilychart,homilylink,DeepChart">
  13. <meta http-equiv="description" content="HomilyLink">
  14. <title>夺宝奇兵免费体验</title>
  15. <script src="https://cdn.tailwindcss.com?v=3.3.5"></script>
  16. <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
  17. <script>
  18. tailwind.config = {
  19. theme: {
  20. extend: {
  21. colors: {
  22. primary: '#3B82F6',
  23. secondary: '#8B5CF6'
  24. }
  25. }
  26. }
  27. }
  28. </script>
  29. <style type="text/tailwindcss">
  30. @layer utilities {
  31. .card-hover {
  32. @apply transition-all duration-300 hover:shadow-xl;
  33. }
  34. .btn-effect {
  35. @apply relative overflow-hidden transition-all duration-300;
  36. }
  37. .btn-effect::after {
  38. content: '';
  39. @apply absolute top-0 left-[-100%] w-full h-full bg-white/20 transform skew-x-12 transition-all duration-500;
  40. }
  41. .btn-effect:hover::after {
  42. @apply left-[100%];
  43. }
  44. .input-focus {
  45. @apply focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none;
  46. }
  47. .form-icon-container {
  48. @apply absolute inset-y-0 left-0 flex items-center pl-3.5 pointer-events-none z-10;
  49. }
  50. .form-icon {
  51. @apply text-gray-500 text-base;
  52. }
  53. .form-group {
  54. @apply mb-5 relative;
  55. }
  56. .form-label {
  57. @apply block text-gray-700 font-medium mb-2;
  58. }
  59. .form-control {
  60. @apply w-full pl-10 py-3 border border-gray-300 rounded-lg input-focus transition-colors;
  61. height: 54px;
  62. }
  63. .form-select {
  64. @apply form-control pr-8 appearance-none bg-white;
  65. background-image: url('data:image/svg+xml;charset=US-ASCII,<svg width=\"20\" height=\"20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" fill=\"%23333\"/></svg>');
  66. background-repeat: no-repeat;
  67. background-position: right 0.5rem center;
  68. background-size: 1em;
  69. }
  70. }
  71. </style>
  72. <style>
  73. @keyframes fadeIn {
  74. from {
  75. opacity: 0;
  76. transform: translateY(10px);
  77. }
  78. to {
  79. opacity: 1;
  80. transform: translateY(0);
  81. }
  82. }
  83. .fade-in {
  84. animation: fadeIn 0.5s ease-out forwards;
  85. }
  86. .delay-100 {
  87. animation-delay: 0.1s;
  88. }
  89. .delay-200 {
  90. animation-delay: 0.2s;
  91. }
  92. .delay-300 {
  93. animation-delay: 0.3s;
  94. }
  95. input.form-control,
  96. select.form-select {
  97. box-sizing: border-box;
  98. vertical-align: middle;
  99. }
  100. select.form-select {
  101. -webkit-appearance: none;
  102. -moz-appearance: none;
  103. appearance: none;
  104. }
  105. .loading-overlay {
  106. position: fixed;
  107. top: 0;
  108. left: 0;
  109. right: 0;
  110. bottom: 0;
  111. background: rgba(0, 0, 0, 0.6);
  112. display: flex;
  113. align-items: center;
  114. justify-content: center;
  115. z-index: 9999;
  116. flex-direction: column;
  117. }
  118. .spinner {
  119. width: 50px;
  120. height: 50px;
  121. border: 4px solid #f3f3f3;
  122. border-top: 4px solid #3B82F6;
  123. border-radius: 50%;
  124. animation: spin 1s linear infinite;
  125. }
  126. @keyframes spin {
  127. 0% {
  128. transform: rotate(0deg);
  129. }
  130. 100% {
  131. transform: rotate(360deg);
  132. }
  133. }
  134. .loading-text {
  135. color: white;
  136. margin-top: 15px;
  137. font-size: 16px;
  138. }
  139. button:disabled {
  140. cursor: not-allowed;
  141. }
  142. </style>
  143. </head>
  144. <body class="bg-gray-50 text-gray-800 font-sans">
  145. <header class="fixed top-0 left-0 right-0 bg-white/95 shadow-sm z-50">
  146. <div class="container mx-auto px-4 py-4 flex justify-between items-center">
  147. <div class="flex items-center space-x-2">
  148. <div
  149. class="w-10 h-10 rounded-lg bg-gradient-to-r from-primary to-secondary flex items-center justify-center">
  150. <img alt="夺宝奇兵" src="https://hc.homilychart.com/hc/250121/img/20230711171637.png"
  151. style="width: 40px;height: 40px;">
  152. </div>
  153. <span
  154. class="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-secondary">夺宝奇兵免费体验</span>
  155. </div>
  156. <nav class="hidden md:flex items-center space-x-8">
  157. <a href="hkhcdbqb.html" class="hover:text-primary transition-colors">首页</a>
  158. <a href="hkhcdbqbDownload.html" class="hover:text-primary transition-colors">下载中心</a>
  159. <a href="hkhcdbqbGuide.html" class="text-primary font-medium">操作指南</a>
  160. <a href="https://wa.me/85269518757?text=我要了解夺宝奇兵" target="_blank"
  161. class="px-5 py-2 rounded-full bg-gradient-to-r from-primary to-secondary text-white hover:shadow-lg transition-all">联系我们</a>
  162. </nav>
  163. <button id="mobileMenuBtn" class="md:hidden text-xl">
  164. <i class="fa fa-bars"></i>
  165. </button>
  166. </div>
  167. <div id="mobileMenu" class="md:hidden hidden bg-white border-t">
  168. <div class="container mx-auto px-4 py-3 flex flex-col space-y-3">
  169. <a href="hkhcdbqb.html" class="py-2 hover:text-primary transition-colors">首页</a>
  170. <a href="hkhcdbqbDownload.html" class="py-2 hover:text-primary transition-colors">下载中心</a>
  171. <a href="hkhcdbqbGuide.html" class="py-2 text-primary">操作指南</a>
  172. <a href="https://wa.me/85269518757?text=我要了解夺宝奇兵" target="_blank"
  173. class="py-2 mt-2 rounded-full bg-gradient-to-r from-primary to-secondary text-white text-center">联系我们</a>
  174. </div>
  175. </div>
  176. </header>
  177. <main class="pt-28 pb-16 px-4">
  178. <div class="container mx-auto max-w-6xl">
  179. <div class="text-center mb-12 fade-in">
  180. <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold mb-4">夺宝奇兵+内部班级课程<br />免费体验</h1>
  181. <p class="text-gray-600 max-w-2xl mx-auto">AD粉报名即可获得体验的机会!<br />超级云脑 夺宝利剑 AI预测大模型</p>
  182. </div>
  183. <div class="grid grid-cols-1 lg:grid-cols-5 gap-8 max-w-5xl mx-auto">
  184. <div class="lg:col-span-3 fade-in delay-100">
  185. <div class="bg-white rounded-xl shadow-md p-6 md:p-8 card-hover">
  186. <!-- 保持原有 action 和 method,但用 JS 拦截处理 -->
  187. <form id="registrationForm" action="./hkRegisterTip.html" method="post">
  188. <div class="form-group">
  189. <label class="form-label">姓名 <span class="text-red-500">*</span></label>
  190. <div class="relative">
  191. <div class="form-icon-container">
  192. <i class="form-icon fa fa-user"></i>
  193. </div>
  194. <input type="text" id="unameinfo" name="unameinfo" class="form-control"
  195. autocomplete="off" placeholder="请输入您的姓名">
  196. </div>
  197. <div id="nameError" class="text-red-500 text-sm mt-1" style="display: none;">请输入您的姓名
  198. </div>
  199. </div>
  200. <div class="form-group">
  201. <label class="form-label">手机号码 <span class="text-red-500">*</span></label>
  202. <input type="hidden" name="zbtype" id="zbtype" value="2">
  203. <div class="flex gap-3">
  204. <div class="w-30 relative">
  205. <div class="form-icon-container">
  206. <i class="form-icon fa fa-globe"></i>
  207. </div>
  208. <select name="countryinfo" id="countryinfo" class="form-select">
  209. <option value="+65">+65 新加坡</option>
  210. <option value="+60">+60 马来西亚</option>
  211. <option value="+852">+852 香港</option>
  212. <option value="+1" selected="selected">+1 美国</option>
  213. <option value="+62">+62 印尼</option>
  214. <option value="+61">+61 澳大利亚</option>
  215. <option value="+673">+673 文莱</option>
  216. <option value="+886">+886 台湾</option>
  217. <option value="+86">+86 中国</option>
  218. <option value="+0">+0 其他</option>
  219. <option value="+64">+64 新西兰</option>
  220. <option value="+44">+44 英国</option>
  221. <option value="+81">+81 日本</option>
  222. <option value="+49">+49 德国</option>
  223. <option value="+82">+82 韩国</option>
  224. <option value="+84">+84 越南</option>
  225. <option value="+971">+971 阿联酋</option>
  226. <option value="+45">+45 丹麦</option>
  227. <option value="+853">+853 澳门</option>
  228. <option value="+66">+66 泰国</option>
  229. <option value="+91">+91 印度</option>
  230. <option value="+41">+41 瑞士</option>
  231. <option value="+358">+358 芬兰</option>
  232. <option value="+33">+33 法国</option>
  233. <option value="+63">+63 菲律宾</option>
  234. <option value="+31">+31 荷兰</option>
  235. <option value="+46">+46 瑞典</option>
  236. <option value="+34">+34 西班牙</option>
  237. <option value="+54">+54 阿根廷</option>
  238. <option value="+39">+39 意大利</option>
  239. <option value="+7">+7 俄罗斯</option>
  240. <option value="+420">+420 捷克</option>
  241. </select>
  242. </div>
  243. <div class="flex-1 relative">
  244. <div class="form-icon-container">
  245. <i class="form-icon fa fa-whatsapp"></i>
  246. </div>
  247. <input type="tel" id="umoblie" name="umoblie" class="form-control"
  248. onkeyup="value=value.replace(/[^\d]/g,'').replace(/^0/g,'')"
  249. autocomplete="off" placeholder="不带国家编号的纯机号">
  250. </div>
  251. </div>
  252. <div id="phoneError" class="text-red-500 text-sm mt-1" style="display: none;">
  253. 请输入正确的手机号(纯手机号,不含国家编号)</div>
  254. </div>
  255. <div class="form-group">
  256. <label class="form-label">微信ID</label>
  257. <div class="relative">
  258. <div class="form-icon-container">
  259. <i class="form-icon fa fa-weixin"></i>
  260. </div>
  261. <input type="text" id="uwechat" name="uwechat" class="form-control"
  262. placeholder="微信ID(如没有WhatsApp)" autocomplete="off">
  263. </div>
  264. </div>
  265. <div class="form-group mb-6">
  266. <label class="form-label">邮箱地址 <span class="text-red-500">*</span></label>
  267. <div class="relative">
  268. <div class="form-icon-container">
  269. <i class="form-icon fa fa-envelope"></i>
  270. </div>
  271. <input type="email" id="uemail" name="uemail" class="form-control"
  272. autocomplete="off" placeholder="请输入您的邮箱地址">
  273. </div>
  274. <div id="emailError" class="text-red-500 text-sm mt-1" style="display: none;">
  275. 请输入您的有效邮箱地址</div>
  276. </div>
  277. <button type="submit" id="submitBtn"
  278. class="btn-effect w-full py-3 rounded-lg bg-gradient-to-r from-primary to-secondary text-white font-medium text-lg">
  279. <i class="fa fa-check-circle mr-2"></i>提交注册
  280. </button>
  281. <p class="text-center text-gray-500 text-sm mt-4">
  282. 如需帮助?<a href="https://wa.me/85269518757?text=我要体验DEEPCHART" target="_blank"
  283. class="text-primary hover:underline">点击发WhatsApp</a>
  284. </p>
  285. </form>
  286. </div>
  287. </div>
  288. <div class="lg:col-span-2 fade-in delay-200">
  289. <div class="bg-white rounded-xl shadow-md p-6 md:p-8 h-full card-hover">
  290. <h3 class="text-xl font-bold mb-5 flex items-center">
  291. <i class="fa fa-info-circle text-primary mr-2"></i>注册说明
  292. </h3>
  293. <div class="space-y-4 text-gray-600">
  294. <div class="flex">
  295. <div
  296. class="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-primary flex-shrink-0 mr-3 mt-0.5">
  297. <i class="fa fa-user"></i>
  298. </div>
  299. <p>请填写方便称呼您的姓名信息。</p>
  300. </div>
  301. <div class="flex">
  302. <div
  303. class="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-primary flex-shrink-0 mr-3 mt-0.5">
  304. <i class="fa fa-whatsapp"></i>
  305. </div>
  306. <p>手机号码最好支持WhatsApp联系。</p>
  307. </div>
  308. <div class="flex">
  309. <div
  310. class="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-primary flex-shrink-0 mr-3 mt-0.5">
  311. <i class="fa fa-weixin"></i>
  312. </div>
  313. <p>微信的联系方式我们也支持。</p>
  314. </div>
  315. <div class="flex">
  316. <div
  317. class="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-primary flex-shrink-0 mr-3 mt-0.5">
  318. <i class="fa fa-envelope"></i>
  319. </div>
  320. <p>邮箱作为联系您的备用联系方式。</p>
  321. </div>
  322. <div class="mt-6 pt-5 border-t border-gray-100">
  323. <h4 class="font-semibold mb-3 text-gray-700">温馨提示</h4>
  324. <p class="text-sm">
  325. AD粉可以进入HomilyLink内部班级群<br />免费学习。<br />免费体验包括:夺宝奇兵三大模板<br />铁粉可以体验部分DeepChart功能!</p>
  326. </div>
  327. <div class="mt-6 pt-5 border-t border-gray-100">
  328. <h4 class="font-semibold mb-3 text-gray-700">郑重声明</h4>
  329. <p class="text-sm">我们将严格保护您的个人信息安全,绝对不会向第三方泄露。</p>
  330. </div>
  331. </div>
  332. </div>
  333. </div>
  334. </div>
  335. </div>
  336. </main>
  337. <footer class="bg-gray-900 text-white py-10 px-4 mt-16">
  338. <div class="container mx-auto max-w-6xl text-center">
  339. <div class="mb-6">
  340. <div class="inline-flex items-center space-x-2">
  341. <div class="w-10 h-10 rounded-lg gradient-bg flex items-center justify-center">
  342. <img alt="夺宝奇兵" src="https://hc.homilychart.com/hc/250121/img/20230711171637.png"
  343. style="width: 40px;height: 40px;">
  344. </div>
  345. <span class="font-bold">夺宝奇兵免费体验</span>
  346. </div>
  347. </div>
  348. <p class="text-gray-400 text-sm mb-4">Copyright 2026.Capitalmaster Pte Ltd All Rights Reserved.</p>
  349. </div>
  350. </footer>
  351. <script type="module">
  352. import { registerMemberApi } from './src/api/hkmember.js';
  353. const form = document.getElementById('registrationForm');
  354. const submitBtn = document.getElementById('submitBtn');
  355. const nameError = document.getElementById('nameError');
  356. const phoneError = document.getElementById('phoneError');
  357. const emailError = document.getElementById('emailError');
  358. // ========== 清理残留loading ==========
  359. function cleanupLoading() {
  360. const existingOverlay = document.getElementById('loadingOverlay');
  361. if (existingOverlay) existingOverlay.remove();
  362. if (submitBtn) {
  363. submitBtn.disabled = false;
  364. submitBtn.style.opacity = '1';
  365. submitBtn.innerHTML = '<i class="fa fa-check-circle mr-2"></i>提交注册';
  366. }
  367. sessionStorage.removeItem('isSubmitting');
  368. }
  369. function hideAllErrors() {
  370. if (nameError) nameError.style.display = 'none';
  371. if (phoneError) phoneError.style.display = 'none';
  372. if (emailError) emailError.style.display = 'none';
  373. }
  374. function showError(element) {
  375. if (element) element.style.display = 'block';
  376. }
  377. function isValidEmail(email) {
  378. if (!email || email.trim() === '') return false;
  379. const emailRegex = /^[^\s@]+@([^\s@]+\.)+[^\s@]+$/;
  380. if (!emailRegex.test(email)) return false;
  381. if (email.length > 254) return false;
  382. if (email.includes('..')) return false;
  383. return true;
  384. }
  385. function isValidPhone(phone) {
  386. if (!phone || phone.trim() === '') return false;
  387. const digitsOnly = phone.replace(/[^\d]/g, '');
  388. if (digitsOnly.length < 4 || digitsOnly.length > 20) return false;
  389. return true;
  390. }
  391. function cleanPhoneNumber(phone) {
  392. if (!phone) return '';
  393. let cleaned = phone.replace(/[^\d]/g, '');
  394. cleaned = cleaned.replace(/^(00)/, '');
  395. return cleaned;
  396. }
  397. function showLoading() {
  398. if (document.getElementById('loadingOverlay')) return;
  399. const loadingDiv = document.createElement('div');
  400. loadingDiv.id = 'loadingOverlay';
  401. loadingDiv.className = 'loading-overlay';
  402. loadingDiv.innerHTML = '<div class="spinner"></div><div class="loading-text">正在提交注册信息...</div>';
  403. document.body.appendChild(loadingDiv);
  404. if (submitBtn) {
  405. submitBtn.disabled = true;
  406. submitBtn.style.opacity = '0.6';
  407. submitBtn.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i>提交中...';
  408. }
  409. sessionStorage.setItem('isSubmitting', 'true');
  410. }
  411. function hideLoading() {
  412. const loadingDiv = document.getElementById('loadingOverlay');
  413. if (loadingDiv) loadingDiv.remove();
  414. if (submitBtn) {
  415. submitBtn.disabled = false;
  416. submitBtn.style.opacity = '1';
  417. submitBtn.innerHTML = '<i class="fa fa-check-circle mr-2"></i>提交注册';
  418. }
  419. sessionStorage.removeItem('isSubmitting');
  420. }
  421. let isSubmitting = false;
  422. // 表单提交 - 先调API,成功后继续表单提交(保持原有跳转)
  423. form.addEventListener('submit', async function (e) {
  424. // 先进行前端校验
  425. hideAllErrors();
  426. const name = document.getElementById('unameinfo').value.trim();
  427. const countryCode = document.getElementById('countryinfo').value;
  428. const phoneRaw = document.getElementById('umoblie').value.trim();
  429. const wechat = document.getElementById('uwechat').value.trim();
  430. const email = document.getElementById('uemail').value.trim();
  431. let isValid = true;
  432. if (!name) {
  433. showError(nameError);
  434. isValid = false;
  435. }
  436. if (!phoneRaw || !isValidPhone(phoneRaw)) {
  437. showError(phoneError);
  438. isValid = false;
  439. }
  440. if (!email || !isValidEmail(email)) {
  441. showError(emailError);
  442. isValid = false;
  443. }
  444. if (!isValid) {
  445. e.preventDefault();
  446. return;
  447. }
  448. // 防止重复提交
  449. if (isSubmitting) {
  450. e.preventDefault();
  451. return;
  452. }
  453. e.preventDefault();
  454. isSubmitting = true;
  455. const cleanedPhone = cleanPhoneNumber(phoneRaw);
  456. const requestData = {
  457. name: name,
  458. code: countryCode,
  459. tel: cleanedPhone,
  460. email: email
  461. };
  462. if (wechat) {
  463. requestData.weChat = wechat;
  464. }
  465. showLoading();
  466. try {
  467. const result = await registerMemberApi(requestData);
  468. if (result.code === 200) {
  469. // API调用成功,继续原有的表单提交(POST到hkRegisterTip.html)
  470. hideLoading();
  471. // 重新提交表单(不再拦截)
  472. isSubmitting = false;
  473. form.submit();
  474. } else {
  475. hideLoading();
  476. isSubmitting = false;
  477. alert('注册失败:' + (result.msg || '未知错误,请稍后重试'));
  478. }
  479. } catch (error) {
  480. console.error('提交注册出错:', error);
  481. hideLoading();
  482. isSubmitting = false;
  483. alert('网络错误或接口异常,请稍后重试');
  484. }
  485. });
  486. // 移动端菜单切换
  487. document.getElementById('mobileMenuBtn').addEventListener('click', function () {
  488. const menu = document.getElementById('mobileMenu');
  489. menu.classList.toggle('hidden');
  490. const icon = this.querySelector('i');
  491. if (icon.classList.contains('fa-bars')) {
  492. icon.classList.replace('fa-bars', 'fa-times');
  493. } else {
  494. icon.classList.replace('fa-times', 'fa-bars');
  495. }
  496. });
  497. // 页面加载动画 + 清理残留loading
  498. document.addEventListener('DOMContentLoaded', function () {
  499. document.querySelectorAll('.fade-in').forEach(el => {
  500. el.style.opacity = '1';
  501. });
  502. cleanupLoading();
  503. });
  504. // 处理浏览器后退/前进时的残留loading
  505. window.addEventListener('pageshow', function (event) {
  506. if (event.persisted) {
  507. cleanupLoading();
  508. }
  509. });
  510. window.addEventListener('popstate', function () {
  511. cleanupLoading();
  512. });
  513. // 实时验证
  514. document.getElementById('unameinfo')?.addEventListener('blur', function () {
  515. if (this.value.trim()) nameError.style.display = 'none';
  516. });
  517. document.getElementById('umoblie')?.addEventListener('blur', function () {
  518. if (this.value.trim() && isValidPhone(this.value.trim())) phoneError.style.display = 'none';
  519. });
  520. document.getElementById('uemail')?.addEventListener('blur', function () {
  521. if (this.value.trim() && isValidEmail(this.value.trim())) emailError.style.display = 'none';
  522. });
  523. </script>
  524. </body>
  525. </html>