forks

Creation chat

ClarkZhang
帮我做一个计算器,有点像房贷计算器。用来让国外的用户计算自己到上海做MRI,并住两天五星酒店的成本与直接在本国(如美国)做MRI的成本。 包括金钱、等待时间等。注意标明大概的汇率换算。 支持双语,优先展示英文,可选中文
04-27 07:55

登录 后可以评论

Assistant
这是为您生成的一个“上海MRI医疗旅行成本计算器”HTML文件。它帮助国外用户比较在上海与本国(如美国)进行MRI检查并入住两晚五星酒店的总成本与等待时间,并支持中英文切换。 (HTML code has been generated and updated; see above for the current version.) ### 成本对比与语言切换 您可以通过调整各项参数,直观地比较两种方案的成本与时间差异。页面核心功能围绕“对比”与“个性化”展开。 - **双栏对比输入**:页面左右两侧分别对应“上海”和“本国”方案。您可以在每个栏位中自由填写MRI费用、酒店价格、机票、等待天数等关键数值,所有输入都会实时触发计算。 - **实时结果与节省分析**:输入变化后,每张卡片的总计金额、页面底部的“可节省金额”以及等待时间对比都会同步更新。节省金额会以绿色(正节省)或红色(超支)高亮显示,一目了然。 - **双语界面切换**:页面右上角提供了“EN”和“中文”切换按钮。点击即可在英文和中文界面间切换,所有标签、说明和提示文字都会同步更新,方便不同语言的用户使用。
▼ Code
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MRI Cost Comparator · 上海 vs 本地</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>tailwind.config = { darkMode: 'class' }</script>
    <style>
        /* 保证 iframe 内显式高度可见 */
        .game-container { min-height: 400px; height: 70vh; max-height: 650px; }
        .touch-none { touch-action: none; }
        /* 自定义弹窗覆盖 */
        #custom-modal { transition: opacity 0.2s; }
    </style>
</head>
<body class="min-h-screen bg-slate-50 dark:bg-slate-900 text-slate-700 dark:text-slate-200 transition-colors">

    <!-- ========== 主题切换按钮 (固定右上角) ========== -->
    <button id="theme-toggle-btn" class="fixed top-4 right-4 z-10 p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors flex items-center justify-center" aria-label="Toggle theme" onclick="toggleTheme()">
        <svg id="icon-moon" class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998z"/></svg>
        <svg id="icon-sun" class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true" style="display:none"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path></svg>
    </button>

    <!-- ========== 自定义弹窗 (提示/确认) ========== -->
    <div id="custom-modal" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 hidden" aria-hidden="true">
        <div class="rounded-xl bg-white dark:bg-slate-800 p-6 shadow-xl max-w-sm w-full border border-slate-200 dark:border-slate-700">
            <p id="custom-modal-msg" class="text-slate-700 dark:text-slate-200 mb-4"></p>
            <button type="button" onclick="hideModal()" class="w-full rounded-lg bg-blue-600 px-4 py-2 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">确定</button>
        </div>
    </div>

    <!-- ========== 主内容区 ========== -->
    <main class="max-w-4xl mx-auto px-4 py-10 sm:py-14">
        <!-- 标题 / 语言切换 -->
        <div class="flex flex-wrap items-center justify-between mb-6">
            <div>
                <h1 class="text-3xl sm:text-4xl font-bold text-slate-900 dark:text-slate-100 tracking-tight">
                    <span class="text-blue-600 dark:text-blue-400">MRI</span> Cost Comparator
                </h1>
                <p class="text-sm mt-1 text-slate-500 dark:text-slate-400" id="subtitle-en">Shanghai vs. your country · 2-night 5★ hotel</p>
                <p class="text-sm mt-1 text-slate-500 dark:text-slate-400 hidden" id="subtitle-zh">上海 vs. 本国 · 两晚五星酒店</p>
            </div>
            <div class="flex gap-2 items-center">
                <span class="text-xs font-medium text-slate-400 dark:text-slate-500">🌐</span>
                <button id="lang-en" class="px-3 py-1 rounded-md text-sm font-medium bg-blue-600 text-white dark:bg-blue-500">EN</button>
                <button id="lang-zh" class="px-3 py-1 rounded-md text-sm font-medium bg-white dark:bg-slate-700 text-slate-600 dark:text-slate-300 border border-slate-300 dark:border-slate-600 hover:bg-slate-100 dark:hover:bg-slate-600">中文</button>
            </div>
        </div>

        <!-- 简介卡片 -->
        <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-5 mb-8">
            <p class="text-sm leading-relaxed" id="intro-en">
                <strong class="text-blue-600 dark:text-blue-400">Compare</strong> the total cost and waiting time of getting an MRI in Shanghai 
                (including a 2-night stay at a 5-star hotel) vs. getting one in your home country. 
                <span class="text-amber-600 dark:text-amber-400">💡 All costs are estimates</span> — adjust the numbers based on your own situation.
            </p>
            <p class="text-sm leading-relaxed hidden" id="intro-zh">
                <strong class="text-blue-600 dark:text-blue-400">比较</strong> 在上海做MRI(含两晚五星酒店)与在本国做MRI的总花费及等待时间。
                <span class="text-amber-600 dark:text-amber-400">💡 所有费用均为估算</span> — 可根据自身情况调整数值。
            </p>
        </div>

        <!-- 计算器主体:两个卡片对比 -->
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
            <!-- 上海卡片 -->
            <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-5">
                <div class="flex items-center gap-2 mb-4">
                    <span class="text-2xl">🏥</span>
                    <h2 class="text-xl font-semibold text-slate-900 dark:text-slate-100" id="sh-title">Shanghai</h2>
                </div>
                <div class="space-y-4">
                    <div>
                        <label class="block text-sm font-medium mb-1" id="sh-mri-label">MRI cost (USD)</label>
                        <input type="number" id="sh-mri" value="450" min="100" max="5000" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                    <div>
                        <label class="block text-sm font-medium mb-1" id="sh-hotel-label">Hotel / night (USD) · 5★</label>
                        <input type="number" id="sh-hotel" value="180" min="50" max="2000" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                    <div>
                        <label class="block text-sm font-medium mb-1" id="sh-flight-label">Round-trip flight (USD)</label>
                        <input type="number" id="sh-flight" value="800" min="0" max="10000" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                    <div>
                        <label class="block text-sm font-medium mb-1" id="sh-wait-label">Waiting time (days)</label>
                        <input type="number" id="sh-wait" value="3" min="0" max="60" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                </div>
                <div class="mt-5 pt-4 border-t border-slate-200 dark:border-slate-700">
                    <p class="text-sm text-slate-500 dark:text-slate-400" id="sh-total-label">Estimated total</p>
                    <p class="text-2xl font-bold text-blue-600 dark:text-blue-400" id="sh-total">$1,610</p>
                    <p class="text-xs mt-1 text-slate-400 dark:text-slate-500" id="sh-note">* includes 2 nights hotel + flight + MRI</p>
                </div>
            </div>

            <!-- 本国卡片 (美国示例) -->
            <div class="bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-5">
                <div class="flex items-center gap-2 mb-4">
                    <span class="text-2xl">🇺🇸</span>
                    <h2 class="text-xl font-semibold text-slate-900 dark:text-slate-100" id="local-title">Your Country (US)</h2>
                </div>
                <div class="space-y-4">
                    <div>
                        <label class="block text-sm font-medium mb-1" id="local-mri-label">MRI cost (USD)</label>
                        <input type="number" id="local-mri" value="2500" min="100" max="20000" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                    <div>
                        <label class="block text-sm font-medium mb-1" id="local-wait-label">Waiting time (days)</label>
                        <input type="number" id="local-wait" value="21" min="0" max="120" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                    <div>
                        <label class="block text-sm font-medium mb-1" id="local-other-label">Other costs (USD, optional)</label>
                        <input type="number" id="local-other" value="200" min="0" max="5000" class="w-full rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-700 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 dark:focus:ring-blue-400">
                    </div>
                </div>
                <div class="mt-5 pt-4 border-t border-slate-200 dark:border-slate-700">
                    <p class="text-sm text-slate-500 dark:text-slate-400" id="local-total-label">Estimated total</p>
                    <p class="text-2xl font-bold text-emerald-600 dark:text-emerald-400" id="local-total">$2,700</p>
                    <p class="text-xs mt-1 text-slate-400 dark:text-slate-500" id="local-note">* MRI + other costs (no travel/hotel)</p>
                </div>
            </div>
        </div>

        <!-- 对比摘要 / 汇率信息 -->
        <div class="mt-8 bg-white dark:bg-slate-800 rounded-2xl shadow-sm border border-slate-200 dark:border-slate-700 p-5">
            <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
                <div>
                    <p class="text-sm text-slate-500 dark:text-slate-400" id="compare-label">You could save</p>
                    <p class="text-3xl font-bold text-amber-600 dark:text-amber-400" id="savings-amount">$1,090</p>
                    <p class="text-xs text-slate-400 dark:text-slate-500" id="savings-desc">by choosing Shanghai + 2 nights 5★ hotel</p>
                </div>
                <div class="bg-slate-100 dark:bg-slate-700 rounded-xl px-4 py-3 text-sm">
                    <p class="font-medium text-slate-700 dark:text-slate-200" id="fx-title">💱 Exchange rate reference</p>
                    <p class="text-slate-500 dark:text-slate-400">1 USD ≈ 7.25 CNY <span class="text-xs">(approx)</span></p>
                    <p class="text-slate-500 dark:text-slate-400 mt-1" id="fx-note">Rates may fluctuate. Check real-time before travel.</p>
                </div>
            </div>
            <!-- 等待时间对比 -->
            <div class="mt-4 pt-3 border-t border-slate-200 dark:border-slate-700 grid grid-cols-2 gap-4 text-sm">
                <div>
                    <span class="text-slate-400 dark:text-slate-500" id="wait-sh-label">Shanghai wait:</span>
                    <span class="font-semibold text-slate-800 dark:text-slate-100" id="wait-sh-value">3 days</span>
                </div>
                <div>
                    <span class="text-slate-400 dark:text-slate-500" id="wait-local-label">Local wait:</span>
                    <span class="font-semibold text-slate-800 dark:text-slate-100" id="wait-local-value">21 days</span>
                </div>
            </div>
        </div>

        <!-- 脚注 -->
        <p class="mt-6 text-xs text-center text-slate-400 dark:text-slate-500" id="footer-note">
            * This is a simplified comparison tool. Always verify prices and exchange rates with actual providers.
        </p>
    </main>

    <!-- ========== 交互脚本 ========== -->
    <script>
        (function() {
            // ---------- 主题切换 (已提供,但内部函数需全局) ----------
            window.toggleTheme = function() {
                var el = document.documentElement;
                var isDark = !el.classList.contains('dark');
                el.classList.toggle('dark', isDark);
                localStorage.setItem('theme', isDark ? 'dark' : 'light');
                applyTheme(isDark);
            };
            window.applyTheme = function(isDark) {
                document.getElementById('icon-moon').style.display = isDark ? 'none' : 'block';
                document.getElementById('icon-sun').style.display = isDark ? 'block' : 'none';
            };
            document.addEventListener('DOMContentLoaded', function() {
                var saved = localStorage.getItem('theme');
                var isDark = saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches);
                document.documentElement.classList.toggle('dark', isDark);
                window.applyTheme(isDark);
                // 初始化计算
                calculate();
            });

            // ---------- 自定义弹窗 (全局) ----------
            window.showModal = function(msg) {
                var el = document.getElementById('custom-modal');
                document.getElementById('custom-modal-msg').textContent = msg || '';
                el.classList.remove('hidden');
            };
            window.hideModal = function() {
                document.getElementById('custom-modal').classList.add('hidden');
            };

            // ---------- 计算逻辑 ----------
            function calculate() {
                // 获取上海输入
                var shMri = parseFloat(document.getElementById('sh-mri').value) || 0;
                var shHotel = parseFloat(document.getElementById('sh-hotel').value) || 0;
                var shFlight = parseFloat(document.getElementById('sh-flight').value) || 0;
                var shWait = parseInt(document.getElementById('sh-wait').value) || 0;
                // 本地输入
                var localMri = parseFloat(document.getElementById('local-mri').value) || 0;
                var localWait = parseInt(document.getElementById('local-wait').value) || 0;
                var localOther = parseFloat(document.getElementById('local-other').value) || 0;

                // 上海总花费: MRI + 2晚酒店 + 往返机票
                var shTotal = shMri + (shHotel * 2) + shFlight;
                // 本地总花费: MRI + 其他
                var localTotal = localMri + localOther;

                // 更新显示
                document.getElementById('sh-total').textContent = '$' + shTotal.toFixed(0);
                document.getElementById('local-total').textContent = '$' + localTotal.toFixed(0);

                // 节省金额
                var savings = localTotal - shTotal;
                var savingsEl = document.getElementById('savings-amount');
                if (savings > 0) {
                    savingsEl.textContent = '$' + savings.toFixed(0);
                    savingsEl.className = 'text-3xl font-bold text-emerald-600 dark:text-emerald-400';
                } else if (savings < 0) {
                    savingsEl.textContent = '$' + Math.abs(savings).toFixed(0) + ' more';
                    savingsEl.className = 'text-3xl font-bold text-rose-600 dark:text-rose-400';
                } else {
                    savingsEl.textContent = '$0';
                    savingsEl.className = 'text-3xl font-bold text-slate-500 dark:text-slate-400';
                }

                // 等待时间
                document.getElementById('wait-sh-value').textContent = shWait + ' day' + (shWait !== 1 ? 's' : '');
                document.getElementById('wait-local-value').textContent = localWait + ' day' + (localWait !== 1 ? 's' : '');

                console.log('[MRI计算器] 上海总花费:', shTotal, '本地总花费:', localTotal, '节省:', savings);
            }

            // ---------- 绑定输入事件 ----------
            var inputs = document.querySelectorAll('input[type="number"]');
            inputs.forEach(function(inp) {
                inp.addEventListener('input', calculate);
                inp.addEventListener('change', calculate);
            });

            // ---------- 语言切换 (EN / 中文) ----------
            var langEN = document.getElementById('lang-en');
            var langZH = document.getElementById('lang-zh');
            var isEN = true; // 默认英文

            function setLanguage(en) {
                isEN = en;
                // 切换按钮样式
                if (en) {
                    langEN.className = 'px-3 py-1 rounded-md text-sm font-medium bg-blue-600 text-white dark:bg-blue-500';
                    langZH.className = 'px-3 py-1 rounded-md text-sm font-medium bg-white dark:bg-slate-700 text-slate-600 dark:text-slate-300 border border-slate-300 dark:border-slate-600 hover:bg-slate-100 dark:hover:bg-slate-600';
                } else {
                    langZH.className = 'px-3 py-1 rounded-md text-sm font-medium bg-blue-600 text-white dark:bg-blue-500';
                    langEN.className = 'px-3 py-1 rounded-md text-sm font-medium bg-white dark:bg-slate-700 text-slate-600 dark:text-slate-300 border border-slate-300 dark:border-slate-600 hover:bg-slate-100 dark:hover:bg-slate-600';
                }

                // 显示/隐藏对应文案
                document.getElementById('subtitle-en').classList.toggle('hidden', !en);
                document.getElementById('subtitle-zh').classList.toggle('hidden', en);
                document.getElementById('intro-en').classList.toggle('hidden', !en);
                document.getElementById('intro-zh').classList.toggle('hidden', en);
                // 标题
                document.getElementById('sh-title').textContent = en ? 'Shanghai' : '上海';
                document.getElementById('local-title').textContent = en ? 'Your Country (US)' : '本国 (美国)';
                // 标签
                document.getElementById('sh-mri-label').textContent = en ? 'MRI cost (USD)' : 'MRI 费用 (美元)';
                document.getElementById('sh-hotel-label').textContent = en ? 'Hotel / night (USD) · 5★' : '酒店/晚 (美元) · 五星';
                document.getElementById('sh-flight-label').textContent = en ? 'Round-trip flight (USD)' : '往返机票 (美元)';
                document.getElementById('sh-wait-label').textContent = en ? 'Waiting time (days)' : '等待时间 (天)';
                document.getElementById('local-mri-label').textContent = en ? 'MRI cost (USD)' : 'MRI 费用 (美元)';
                document.getElementById('local-wait-label').textContent = en ? 'Waiting time (days)' : '等待时间 (天)';
                document.getElementById('local-other-label').textContent = en ? 'Other costs (USD, optional)' : '其他费用 (美元, 可选)';
                // 总计标签
                document.getElementById('sh-total-label').textContent = en ? 'Estimated total' : '预估总计';
                document.getElementById('local-total-label').textContent = en ? 'Estimated total' : '预估总计';
                document.getElementById('sh-note').textContent = en ? '* includes 2 nights hotel + flight + MRI' : '* 含两晚酒店+机票+MRI';
                document.getElementById('local-note').textContent = en ? '* MRI + other costs (no travel/hotel)' : '* MRI + 其他费用 (不含旅行/酒店)';
                // 对比区域
                document.getElementById('compare-label').textContent = en ? 'You could save' : '您可节省';
                document.getElementById('savings-desc').textContent = en ? 'by choosing Shanghai + 2 nights 5★ hotel' : '选择上海 + 两晚五星酒店';
                document.getElementById('fx-title').textContent = en ? '💱 Exchange rate reference' : '💱 汇率参考';
                document.getElementById('fx-note').textContent = en ? 'Rates may fluctuate. Check real-time before travel.' : '汇率可能波动,出行前请查询实时汇率。';
                document.getElementById('wait-sh-label').textContent = en ? 'Shanghai wait:' : '上海等待:';
                document.getElementById('wait-local-label').textContent = en ? 'Local wait:' : '本地等待:';
                document.getElementById('footer-note').textContent = en ? 
                    '* This is a simplified comparison tool. Always verify prices and exchange rates with actual providers.' :
                    '* 此为简化比较工具,请务必向实际服务商核实价格与汇率。';
                // 提示弹窗也更新?不需要,动态内容
                console.log('[语言] 切换为', en ? 'English' : '中文');
            }

            langEN.addEventListener('click', function() { setLanguage(true); });
            langZH.addEventListener('click', function() { setLanguage(false); });

            // 初始化计算
            calculate();
            // 默认英文
            setLanguage(true);

            // 额外:点击计算器任何地方不会触发页面滚动 (touch-action)
        })();
    </script>

    <!-- 确保touch-action: manipulation 消除延迟 -->
    <style>
        button, input, .touch-manipulation { touch-action: manipulation; }
    </style>
</body>
</html>
04-27 07:57

登录 后可以评论

Comments

登录 后可以评论