|
|
<!DOCTYPE html><html lang="zh-CN">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <link rel="shortcut icon" href="dbqb_favicon.ico" /> <link rel="Bookmark" href="dbqb_favicon.ico" /> <meta http-equiv="keywords" content="夺宝奇兵,意见反馈,用户反馈"> <meta http-equiv="description" content="夺宝奇兵用户意见反馈页面"> <title>夺宝奇兵 - 意见反馈</title> <!-- 引入外部资源 --> <script src="https://cdn.tailwindcss.com?v=3.3.5"></script> <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- 基础样式配置 --> <script> tailwind.config = { theme: { extend: { colors: { primary: '#3B82F6', secondary: '#8B5CF6', danger: '#EF4444', success: '#10B981' } } } } </script>
<style type="text/tailwindcss"> @layer utilities { .input-focus { @apply focus:ring-2 focus:ring-primary/50 focus:border-primary focus:outline-none; } .input-error { @apply border-danger focus:ring-danger/20 focus:border-danger; } .btn-effect { @apply relative overflow-hidden transition-all duration-300; } .btn-effect::after { content: ''; @apply absolute top-0 left-[-100%] w-full h-full bg-white/20 transform skew-x-12 transition-all duration-500; } .btn-effect:hover::after { @apply left-[100%]; } .card-shadow { @apply shadow-md hover:shadow-lg transition-shadow duration-300; } .modal-backdrop { @apply fixed inset-0 bg-black/50 z-50 flex items-center justify-center opacity-0 pointer-events-none transition-opacity duration-300; } .modal-backdrop.active { @apply opacity-100 pointer-events-auto; } .modal-content { @apply bg-white rounded-xl shadow-2xl max-w-md w-full mx-4 transform translate-y-8 transition-transform duration-300; } .modal-backdrop.active .modal-content { @apply translate-y-0; } .error-message { @apply text-danger text-sm mt-1 hidden; } .country-select-container { @apply relative; } .country-select { @apply appearance-none bg-white border border-gray-300 rounded-lg py-3 pl-10 pr-10 input-focus transition-colors w-full; } .loading-spinner { @apply inline-block w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin; } } </style>
<style> /* 确保基础样式生效 */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
/* 简单动画 */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); } }
.fade-in { animation: fadeIn 0.5s ease-out forwards; }
.delay-100 { animation-delay: 0.1s; }
.delay-200 { animation-delay: 0.2s; }
.delay-300 { animation-delay: 0.3s; }
/* 国家选择框箭头样式 */ .country-select-arrow { pointer-events: none; }
/* 国家选择下拉列表样式 */ .country-select option { padding: 8px 12px; }
/* 确保3:7比例在所有中等及以上屏幕生效 */ @media (min-width: 640px) { .whatsapp-container { display: flex; gap: 1rem; }
.country-code-wrapper { width: 30%; }
.phone-number-wrapper { width: 70%; } } </style></head>
<body class="bg-gray-50 text-gray-800"> <!-- 导航栏 --> <header class="fixed top-0 left-0 right-0 bg-white/95 shadow-sm z-50"> <div class="container mx-auto px-4 py-4 flex justify-between items-center"> <div class="flex items-center space-x-2"> <div class="w-10 h-10 rounded-lg bg-gradient-to-r from-primary to-secondary flex items-center justify-center"> <img alt="夺宝奇兵" src="https://hc.homilychart.com/hc/250121/img/20230711171637.png" style="width: 40px;height: 40px;"> </div> <span class="text-xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-primary to-secondary">意见反馈</span> </div>
<!-- 桌面导航 --> <nav class="hidden md:flex items-center space-x-8"> <a href="./hkhcdbqb.html" class="hover:text-primary transition-colors">首页</a> <a href="#" class="text-primary font-medium">意见反馈</a> <a href="https://api.whatsapp.com/send?phone=6588792879&text=夺宝奇兵我需要帮助" target="_blank" class="px-5 py-2 rounded-full bg-gradient-to-r from-primary to-secondary text-white hover:shadow-lg transition-all">联系我们</a> </nav>
<!-- 移动端菜单 --> <button id="mobileMenuBtn" class="md:hidden text-xl"> <i class="fa fa-bars"></i> </button> </div>
<!-- 移动端菜单内容 --> <div id="mobileMenu" class="md:hidden hidden bg-white border-t"> <div class="container mx-auto px-4 py-3 flex flex-col space-y-3"> <a href="#" class="py-2 hover:text-primary transition-colors">首页</a> <a href="#" class="py-2 text-primary">意见反馈</a> <a href="https://api.whatsapp.com/send?phone=6588792879&text=夺宝奇兵我需要帮助" target="_blank" class="py-2 mt-2 rounded-full bg-gradient-to-r from-primary to-secondary text-white text-center">联系我们</a> </div> </div> </header>
<!-- 主要内容 --> <main class="pt-28 pb-16 px-4"> <div class="container mx-auto max-w-4xl"> <!-- 页面标题 --> <div class="text-center mb-12 fade-in"> <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold mb-4">意见反馈</h1> <p class="text-gray-600 max-w-2xl mx-auto">感谢您对Adam说港股团队的支持!<br>请留下您的宝贵意见和建议,我们将不断的提升服务质量!</p> </div>
<!-- 反馈表单卡片 --> <div class="bg-white rounded-xl p-6 md:p-8 mb-10 fade-in delay-100 card-shadow"> <form id="feedbackForm" class="space-y-6"> <!-- 姓名输入 --> <div class="form-group"> <label for="name" class="block text-gray-700 font-medium mb-2">姓名 <span class="text-danger">*</span></label> <div class="relative"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-user"></i> </div> <input type="text" id="fusername" name="fusername" required class="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg input-focus transition-colors" placeholder="请输入您的姓名"> <div class="error-message" id="nameError">请输入您的姓名</div> </div> </div>
<!-- WhatsApp号码 - 精确3:7比例布局 --> <div class="form-group"> <label class="block text-gray-700 font-medium mb-2">Whatsapp <span class="text-danger">*</span></label> <div class="whatsapp-container flex flex-col sm:flex-row gap-3"> <!-- 国家选择(30%宽度) --> <div class="country-code-wrapper country-select-container"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-whatsapp"></i> </div> <select id="countryinfo" name="countryinfo" required class="country-select">
<option value="+65">+65 新加坡</option>
<option value="+60">+60 马来西亚</option>
<option value="+852">+852 香港</option>
<option value="+1" selected='selected'>+1 美国</option>
<option value="+62">+62 印尼</option>
<option value="+1">+1 加拿大</option>
<option value="+61">+61 澳大利亚</option>
<option value="+673">+673 文莱</option>
<option value="+886">+886 台湾</option>
<option value="+86">+86 中国</option>
<option value="+0">+0 其他</option>
<option value="+64">+64 新西兰</option>
<option value="+44">+44 英国</option>
<option value="+81">+81 日本</option>
<option value="+49">+49 德国</option>
<option value="+82">+82 韩国</option>
<option value="+84 ">+84 越南</option>
<option value="+971">+971 阿联酋</option>
<option value="+45">+45 丹麦</option>
<option value="+853">+853 澳门</option>
<option value="+66">+66 泰国</option>
<option value="+91">+91 印度</option>
<option value="+41">+41 瑞士</option>
<option value="+358">+358 芬兰</option>
<option value="+33">+33 法国</option>
<option value="+63">+63 菲律宾</option>
<option value="+31">+31 荷兰</option>
<option value="+46">+46 瑞典</option>
<option value="+34">+34 西班牙</option>
<option value="+54">+54 阿根廷</option>
<option value="+39">+39 意大利</option>
<option value="+7">+7 俄罗斯</option>
<option value="+420">+420 捷克</option>
</select> <div class="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none text-gray-400 country-select-arrow"> <i class="fa fa-chevron-down"></i> </div> <div class="error-message" id="countryCodeError">请选择国家/地区</div> </div>
<!-- 手机号(70%宽度) --> <div class="phone-number-wrapper relative"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-mobile text-lg"></i> </div> <input type="tel" id="umoblie" name="umoblie" required class="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg input-focus transition-colors" placeholder="请输入手机号码"> <div class="error-message" id="phoneError">请输入有效的手机号码</div> </div> </div> </div>
<!-- 微信ID输入 --> <div class="form-group"> <label for="wechatId" class="block text-gray-700 font-medium mb-2">微信ID</label> <div class="relative"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-weixin"></i> </div> <input type="text" id="fwechat" name="fwechat" class="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg input-focus transition-colors" placeholder="请输入您的微信ID(选填)"> </div> </div>
<!-- 邮箱输入 --> <div class="form-group"> <label for="email" class="block text-gray-700 font-medium mb-2">邮箱 <span class="text-danger">*</span></label> <div class="relative"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-envelope"></i> </div> <input type="email" id="femail" name="femail" required class="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg input-focus transition-colors" placeholder="请输入您的邮箱地址"> <div class="error-message" id="emailError">请输入有效的邮箱地址</div> </div> </div>
<!-- 反馈类型 --> <div class="form-group"> <label for="feedbackType" class="block text-gray-700 font-medium mb-2">反馈类型</label> <div class="relative"> <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-tag"></i> </div> <select id="ftype" name="ftype" class="w-full pl-10 pr-10 py-3 border border-gray-300 rounded-lg input-focus transition-colors appearance-none bg-white"> <option value="功能建议">功能建议</option> <option value="问题反馈">问题反馈</option> <option value="体验优化">体验优化</option> <option value="其他建议">其他建议</option> </select> <div class="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none text-gray-400"> <i class="fa fa-chevron-down"></i> </div> </div> </div>
<!-- 反馈内容(增加最大长度500字的实时限制与校验) --> <div class="form-group"> <label for="feedbackContent" class="block text-gray-700 font-medium mb-2">反馈内容 <span class="text-danger">*</span></label> <div class="relative"> <textarea id="fcontent" name="fcontent" rows="5" required maxlength="500" class="w-full px-4 py-3 border border-gray-300 rounded-lg input-focus transition-colors resize-none" placeholder="请详细描述您的意见或建议...(最多500字)"></textarea> <div class="absolute right-3 bottom-3 text-gray-400 text-sm"> <span id="charCount">0</span> / 500 </div> <div class="error-message" id="feedbackContentError">请输入反馈内容(至少10个字符,最多500字)</div> </div> </div>
<!-- 提交按钮 --> <div class="pt-4"> <button type="submit" id="submitBtn" class="btn-effect w-full py-3 px-6 rounded-lg bg-gradient-to-r from-primary to-secondary text-white font-medium text-lg flex items-center justify-center"> <i class="fa fa-paper-plane mr-2"></i> <span>提交反馈</span> <span id="loadingIndicator" class="ml-2 hidden"> <span class="loading-spinner"></span> </span> </button> </div> </form> </div>
<!-- 反馈须知 --> <div class="bg-gradient-to-r from-primary/5 to-secondary/5 border border-primary/20 rounded-xl p-6 mb-16 fade-in delay-200"> <h3 class="font-semibold text-lg text-gray-800 mb-4 flex items-center"> <i class="fa fa-info-circle text-primary mr-2"></i>反馈须知 </h3> <ul class="space-y-2 text-gray-700"> <li class="flex items-start"> <i class="fa fa-check-circle text-success mt-1 mr-2 flex-shrink-0"></i> <span>我们会在1-3个工作日内处理您的反馈并给予回复</span> </li> <li class="flex items-start"> <i class="fa fa-check-circle text-success mt-1 mr-2 flex-shrink-0"></i> <span>带 <span class="text-danger">*</span> 的为必填项,请确保信息准确无误</span> </li> <li class="flex items-start"> <i class="fa fa-check-circle text-success mt-1 mr-2 flex-shrink-0"></i> <span>您的个人信息仅用于反馈跟进,我们将严格保密</span> </li> <li class="flex items-start"> <i class="fa fa-check-circle text-success mt-1 mr-2 flex-shrink-0"></i> <span>反馈内容限500字以内,请合理控制字数</span> </li> </ul> </div> </div> </main>
<!-- 成功弹窗(与参考页面样式一致,点击确定按钮关闭) --> <div id="successModal" class="modal-backdrop" role="dialog" aria-modal="true"> <div class="modal-content p-6"> <div class="text-center"> <div class="w-16 h-16 rounded-full bg-success/20 flex items-center justify-center mx-auto mb-4"> <i class="fa fa-check-circle text-success text-3xl"></i> </div> <h3 class="text-xl font-bold mb-2">反馈成功!</h3> <p class="text-gray-600 mb-6">感谢您的反馈,我们将持续优化更新</p> <button id="closeModalBtn" class="px-6 py-2 bg-gradient-to-r from-primary to-secondary text-white rounded-lg hover:shadow-lg transition-all"> 确定 </button> </div> </div> </div>
<!-- 页脚 --> <footer class="bg-gray-900 text-white py-10 px-4"> <div class="container mx-auto max-w-6xl text-center"> <div class="mb-6"> <div class="inline-flex items-center space-x-2"> <div class="w-10 h-10 rounded-lg gradient-bg flex items-center justify-center"> <img alt="夺宝奇兵" src="https://hc.homilychart.com/hc/250121/img/20230711171637.png " style="width: 40px;height: 40px;"> </div> <span class="font-bold">夺宝奇兵</span> </div> </div> <p class="text-gray-400 text-sm mb-4">Copyright 2026.Capitalmaster Pte Ltd All Rights Reserved.</p> </div> </footer>
<script type="module"> // 从外部文件导入 registerMemberApi 函数 import { registerMemberApi } from './src/api/hkmember.js';
// DOM 元素 const form = document.getElementById('feedbackForm'); const submitBtn = document.getElementById('submitBtn'); const loadingIndicator = document.getElementById('loadingIndicator'); const successModal = document.getElementById('successModal'); const closeModalBtn = document.getElementById('closeModalBtn');
// 字符计数 const fcontent = document.getElementById('fcontent'); const charCount = document.getElementById('charCount');
// 错误提示元素 const nameError = document.getElementById('nameError'); const phoneError = document.getElementById('phoneError'); const emailError = document.getElementById('emailError'); const feedbackContentError = document.getElementById('feedbackContentError');
// 隐藏所有错误提示 function hideAllErrors() { nameError.style.display = 'none'; phoneError.style.display = 'none'; emailError.style.display = 'none'; feedbackContentError.style.display = 'none'; }
// 显示错误提示 function showError(element, message) { if (element) { element.textContent = message; element.style.display = 'block'; } }
// 显示成功弹窗 function showSuccessModal() { successModal.classList.add('active'); }
// 隐藏成功弹窗 function hideSuccessModal() { successModal.classList.remove('active'); }
// 关闭弹窗事件 closeModalBtn.addEventListener('click', hideSuccessModal);
// 点击模态框背景关闭 successModal.addEventListener('click', function (e) { if (e.target === successModal) { hideSuccessModal(); } });
// 邮箱校验 function isValidEmail(email) { const emailRegex = /^[^\s@]+@([^\s@]+\.)+[^\s@]+$/; if (!emailRegex.test(email)) return false; if (email.length > 254) return false; if (email.includes('..')) return false; return true; }
// 手机号校验 function isValidPhone(phone) { if (!phone || phone.trim() === '') return false; const digitsOnly = phone.replace(/[^\d]/g, ''); if (digitsOnly.length < 4 || digitsOnly.length > 20) return false; return true; }
// 清理手机号 function cleanPhoneNumber(phone) { if (!phone) return ''; let cleaned = phone.replace(/[^\d]/g, ''); cleaned = cleaned.replace(/^(00)/, ''); return cleaned; }
// 反馈类型映射 function getFeedbackTypeValue(typeText) { const typeMap = { '功能建议': '1', '问题反馈': '2', '体验优化': '3', '其他建议': '4' }; return typeMap[typeText] || '4'; }
// 字符计数 & 实时限制(确保不超过500字,与maxlength配合) if (fcontent && charCount) { // 初始化显示 charCount.textContent = fcontent.value.length;
fcontent.addEventListener('input', function () { let len = this.value.length; // 双重保险:如果超过500则截断 if (len > 500) { this.value = this.value.substring(0, 500); len = 500; } charCount.textContent = len;
// 实时移除字数超限的错误提示(如果之前是因为超限报错) if (len <= 500 && feedbackContentError && feedbackContentError.style.display === 'block' && feedbackContentError.textContent.includes('最多500字')) { // 但避免移除其他类型错误,通过文本内容判断 if (feedbackContentError.textContent.includes('最多500字')) { feedbackContentError.style.display = 'none'; } } });
// 增加blur时再次校验,保证用户粘贴超长内容时提示 fcontent.addEventListener('blur', function () { let len = this.value.length; if (len > 500) { this.value = this.value.substring(0, 500); charCount.textContent = 500; showError(feedbackContentError, '反馈内容不能超过500字'); } }); }
// 移动端菜单切换 const mobileMenuBtn = document.getElementById('mobileMenuBtn'); if (mobileMenuBtn) { mobileMenuBtn.addEventListener('click', function () { const menu = document.getElementById('mobileMenu'); menu.classList.toggle('hidden'); const icon = this.querySelector('i'); if (icon.classList.contains('fa-bars')) { icon.classList.replace('fa-bars', 'fa-times'); } else { icon.classList.replace('fa-times', 'fa-bars'); } }); }
// 表单提交处理 - 调用API保存数据,成功后显示弹窗,额外校验500字限制 form.addEventListener('submit', async function (e) { e.preventDefault();
// 前端校验 hideAllErrors();
const name = document.getElementById('fusername').value.trim(); const countryCode = document.getElementById('countryinfo').value; const phoneRaw = document.getElementById('umoblie').value.trim(); const wechat = document.getElementById('fwechat').value.trim(); const email = document.getElementById('femail').value.trim(); const feedbackTypeText = document.getElementById('ftype').value; let feedbackContent = document.getElementById('fcontent').value.trim();
let isValid = true;
// 姓名校验 if (!name) { showError(nameError, '请输入您的姓名'); isValid = false; }
// 手机号校验 if (!phoneRaw || !isValidPhone(phoneRaw)) { showError(phoneError, '请输入有效的手机号码'); isValid = false; }
// 邮箱校验 if (!email || !isValidEmail(email)) { showError(emailError, '请输入有效的邮箱地址'); isValid = false; }
// 反馈内容校验: 不能为空且长度必须在10~500之间 if (!feedbackContent) { showError(feedbackContentError, '请输入反馈内容(至少10个字符,最多500字)'); isValid = false; } else { // 重新获取实际内容(防止中间有特殊空格导致长度偏差) const rawLen = feedbackContent.length; if (rawLen < 10) { showError(feedbackContentError, '反馈内容至少需要10个字符,请详细描述'); isValid = false; } else if (rawLen > 500) { // 如果因为某些意外情况(例如直接通过开发者工具修改)导致超长,再次截断并提示 feedbackContent = feedbackContent.substring(0, 500); document.getElementById('fcontent').value = feedbackContent; charCount.textContent = 500; showError(feedbackContentError, '反馈内容不能超过500字,已自动截断'); isValid = false; } }
if (!isValid) { return; }
// 清理手机号 const cleanedPhone = cleanPhoneNumber(phoneRaw);
// 组装请求参数 const requestData = { name: name, code: countryCode, tel: cleanedPhone, email: email, feedback_content: feedbackContent, feedback_type: getFeedbackTypeValue(feedbackTypeText) };
// 微信ID有值才传递 if (wechat) { requestData.weChat = wechat; }
// 显示加载状态 submitBtn.disabled = true; loadingIndicator.classList.remove('hidden');
try { const result = await registerMemberApi(requestData); if (result.code === 200) { // API调用成功,显示成功弹窗 showSuccessModal(); // 清空表单 form.reset(); // 重置字符计数 if (charCount) charCount.textContent = '0'; // 清空所有隐藏错误显示 hideAllErrors(); } else { alert('提交失败:' + (result.msg || '请稍后重试')); } } catch (error) { console.error('提交出错:', error); alert('网络错误或接口异常,请稍后重试'); } finally { submitBtn.disabled = false; loadingIndicator.classList.add('hidden'); } });
// 页面加载动画 document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.fade-in').forEach(el => { el.style.opacity = '1'; }); // 确保字符计数初始正确 if (fcontent && charCount) { charCount.textContent = fcontent.value.length; } }); </script></body>
</html>
|