个人健康减脂数据中心,自用健身减肥工具分享

image

如何使用?

代码一共1454行,在电脑上记事本新建个人健康减脂数据中心.txt文件, 贴入下文的完整代码,然后修改后缀为.html,双击打开即可。

【代码在哪里?】文章首发于博客园, 平台限制, 这里展示不全, 文章原文可随便复制,md格式,在博客园有写,这里为副本,主页个人简介有,这里只展示部分内容, 平台不兼容,无法全发。

为什么弄?

在健身房锻炼的时候,看着健身房的减肥知识有感,回来自己阅读了很多本健身相关的书籍,包括但不限于《健身营养全书》、《学会吃饭》、《肥胖代码》等。打开一些软件,相关的功能都是要充会员才能查看,或者使用起来比较麻烦,我只是想用一用小工具而已。

翻出以前大学时期写过的前端三大件相关的笔记,结合AI辅助、文献、以前写的代码进行整合,于是简单验证了这个想法,自用**。

每次制定健身和减肥计划的时候都得在Excel上进行计算(虽然写了宏命令自动化执行),但是还是不够方便,希望能够方便的实现:

1、告诉我每日总消耗热量(TDEE)是多少,我方便用于设置能量缺口

2、能够根据我设置的能量缺口,计算出我多久能够达到减肥目标,体重如何变化,生成图表

3、能够计算出日期之间的差值,距离目标还有多久,多少天以后是什么日子

4、能够计算出BMI

于是查阅文献,根据自己的基本需求,利用一点时间进行编写完成,现在已经成为自己不可替代常用小工具了。

本工具只是个人开发来满足基本需求的,现在开源出来给感兴趣的朋友使用。

小工具是闲暇之余简单写写的,比较简陋,还有很多地方可以改进,比较简单,感兴趣的朋友可以继续完善。

有什么功能?

1、计算每日总消耗热量(TDEE)是多少,用于设置能量缺口,计算原理如下,还能在计算后根据不同软件差异(有些体脂秤会有100大卡左右的BMR差距)进行校准,实现二次计算。计算完毕后还能导出报告,附加励志语。

能量缺口范围: 500~750大卡,低于或高于这个范围都不行。能量缺口超过750大卡,可能会导致一系列的营养缺乏。 不足可能由于计算误差, 导致减肥失败.

Mifflin-St Jeor 公式是一个用于计算基础代谢率(BMR) 的公式。男性和女性的公式不同:男性公式为 (10 × 体重(公斤)) + (6.25 × 身高(公分)) - (5 × 年龄(岁)) + 5,女性公式为 (10 × 体重(公斤)) + (6.25 × 身高(公分)) - (5 × 年龄(岁)) - 161。

TDEE每日总能量消耗=基础热量BMR+非运动性活动产热NEAT+运动能量消耗EAT(例如健身房锻炼或跑步等)+TEF食物热效应

由于吃的食物每天都不一样,TEF不好计算,且占比不高,直接忽略,这样会让总消耗热量减少,会潜在增加能量缺口,更容易减肥。

image

2、能够根据设置的能量缺口,计算出多久能够达到减肥目标,体重如何变化,生成图表

image

3、能够计算出日期之间的差值,距离目标还有多久,多少天以后是什么日子

image

4、能够计算出BMI,并进行判断

image

let category = "";
        if (bmi < 18.5) category = "体重过轻";
        else if (bmi < 24) category = "正常范围";
        else if (bmi < 28) category = "超重";
        else category = "肥胖";

完整代码

点击查看代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>个人健康数据中心 V0.42</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <link
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Orbitron:wght@400;500;700&family=Fira+Code&display=swap"
      rel="stylesheet"
    />

    <!-- Aplayer 播放器样式 -->
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css"
    />

    <style>
      :root {
        --bg-color: #111827;
        --card-bg: #1f2937;
        --primary-color: #0ea5e9;
        --text-color: #d1d5db;
        --header-font: "Orbitron", sans-serif;
        --body-font: "Inter", sans-serif;
        --mono-font: "Fira Code", monospace;
      }
      body {
        background-color: var(--bg-color);
        color: var(--text-color);
        font-family: var(--body-font);
        overflow: hidden;
      }
      .bg-canvas {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        /* V0.42 Fix: Allow clicks to pass through the canvas */
        pointer-events: none;
      }
      #matrix-canvas {
        z-index: -2;
      }
      #bg-canvas {
        z-index: -1;
      }

      .main-layout {
        display: flex;
        height: 100vh;
      }

      /* 终端样式 */
      #terminal-wrapper {
        width: 33.333333%;
        height: 100vh;
        background-color: rgba(0, 0, 0, 0.8);
        backdrop-filter: blur(5px);
        border-right: 1px solid var(--primary-color);
        padding: 1rem;
        display: flex;
        flex-direction: column;
        transition: width 0.3s ease-in-out, padding 0.3s ease-in-out;
        overflow: hidden;
      }
      #terminal-wrapper.hidden {
        width: 0;
        padding: 0;
      }
      #terminal-header {
        font-family: var(--header-font);
        color: var(--primary-color);
        margin-bottom: 1rem;
        flex-shrink: 0;
      }
      #terminal-content {
        flex-grow: 1;
        overflow-y: auto;
        white-space: pre-wrap;
        word-wrap: break-word;
        font-family: var(--mono-font);
        font-size: 0.875rem;
      }
      #terminal-content .line {
        display: block;
      }
      #terminal-content .line.success {
        color: #22c55e;
      }
      #terminal-content .line.info {
        color: #3b82f6;
      }
      #terminal-content .line.warn {
        color: #eab308;
      }
      #terminal-content .line.data {
        color: #a78bfa;
      }
      #terminal-idle-animation {
        white-space: pre;
        line-height: 1.2;
        margin-top: 1rem;
        color: var(--primary-color);
        font-size: 0.75rem;
      }

      /* 主内容区 */
      #main-content {
        width: 66.666667%;
        height: 100vh;
        transition: width 0.3s ease-in-out;
        position: relative;
      }
      #main-content.full-width {
        width: 100%;
      }
      .app-container {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .app-view {
        display: none;
      }
      .app-view.active {
        display: block;
        animation: fadeIn 0.5s ease-in-out;
      }
      @keyframes fadeIn {
        from {
          opacity: 0;
          transform: scale(0.98);
        }
        to {
          opacity: 1;
          transform: scale(1);
        }
      }

      /* 开机动画 */
      #loading-view {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 999;
        background-color: var(--bg-color);
      }
      #loading-view .shape {
        position: absolute;
        border-radius: 50%;
        background: var(--primary-color);
        opacity: 0;
        animation: float 8s infinite ease-in-out;
      }
      @keyframes float {
        0%,
        100% {
          transform: translateY(0) scale(1);
          opacity: 0;
        }
        50% {
          transform: translateY(-100px) scale(1.2);
          opacity: 0.6;
        }
      }

      /* 终端切换按钮 */
      #terminal-toggle {
        position: absolute;
        top: 1rem;
        left: 1rem;
        z-index: 150;
        background-color: var(--card-bg);
        color: var(--text-color);
        border: 1px solid #4b5563;
        border-radius: 50%;
        width: 40px;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.3s;
        pointer-events: auto; /* Ensure button is clickable */
      }
      #terminal-toggle:hover {
        background-color: var(--primary-color);
        color: white;
      }

      /* 通用样式 */
      .card {
        background-color: rgba(31, 41, 55, 0.8);
        backdrop-filter: blur(10px);
        border-radius: 0.75rem;
        padding: 1.5rem;
        border: 1px solid #374151;
        max-height: 90vh;
        overflow-y: auto;
      }
      .menu-button {
        background-color: rgba(31, 41, 55, 0.8);
        backdrop-filter: blur(10px);
        border: 1px solid #374151;
        padding: 1.5rem;
        border-radius: 0.75rem;
        text-align: center;
        cursor: pointer;
        transition: all 0.3s ease;
        font-family: var(--header-font);
      }
      .menu-button:hover {
        transform: translateY(-5px);
        background-color: #374151;
        border-color: var(--primary-color);
      }
      .result-box {
        background-color: var(--bg-color);
        border-radius: 0.5rem;
        padding: 1rem;
        margin-top: 1.5rem;
        text-align: center;
        border: 1px solid #374151;
      }
      .btn {
        background-color: var(--primary-color);
        color: white;
        font-weight: 600;
        padding: 0.75rem 1.5rem;
        border-radius: 0.5rem;
        border: none;
        cursor: pointer;
        transition: background-color 0.3s ease;
        width: 100%;
      }
      .btn-secondary {
        background-color: #4b5563;
      }
      .btn:hover {
        background-color: #0284c7;
      }
      .btn-secondary:hover {
        background-color: #6b7280;
      }
      label {
        display: block;
        margin-bottom: 0.25rem;
        font-size: 0.875rem;
        color: #9ca3af;
      }
      input,
      select {
        width: 100%;
        padding: 0.75rem;
        border: 1px solid #4b5563;
        border-radius: 0.375rem;
        background-color: #374151;
        color: var(--text-color);
      }
      .tab-button {
        flex: 1;
        padding: 0.5rem;
        cursor: pointer;
        background-color: #374151;
        border: 1px solid #4b5563;
        color: #9ca3af;
        transition: all 0.2s;
      }
      .tab-button.active {
        background-color: var(--primary-color);
        color: white;
        border-color: var(--primary-color);
      }
      .unit-toggle {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        gap: 0.5rem;
        margin-bottom: 1rem;
      }
      .unit-toggle span {
        cursor: pointer;
        padding: 0.25rem 0.5rem;
        border-radius: 0.25rem;
      }
      .unit-toggle span.active {
        background-color: var(--primary-color);
        color: white;
      }

      /* 报告与UI内表格样式 */
      #report-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.7);
        z-index: 200;
        display: none;
        align-items: center;
        justify-content: center;
      }
      .data-table {
        width: 100%;
        margin-top: 1rem;
        border-collapse: collapse;
        font-size: 0.875rem;
      }
      .data-table th,
      .data-table td {
        border: 1px solid #4b5563;
        padding: 0.5rem;
        text-align: left;
      }
      .data-table th {
        background-color: #374151;
      }
    </style>
  </head>
  <body>
    <canvas id="matrix-canvas" class="bg-canvas"></canvas>
    <canvas id="bg-canvas" class="bg-canvas"></canvas>

    <!-- Aplayer 播放器容器 -->
    <div
      id="my-aplayer"
      class="aplayer"
      data-id="6895409634"
      data-server="netease"
      data-type="playlist"
      data-fixed="true"
      data-autoplay="true"
      data-order="random"
      data-volume="0.7"
      data-theme="#2EA7E0"
      data-preload="auto"
      data-listFolded="true"
    ></div>

    <!-- 开机动画 -->
    <div id="loading-view" class="app-view active">
      <h1
        class="text-4xl font-bold text-center absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
        style="font-family: var(--header-font)"
      >
        HEALTH DATA CENTER
      </h1>
    </div>

    <div class="main-layout">
      <!-- 终端 -->
      <div id="terminal-wrapper">
        <div id="terminal-header">HDC_TERMINAL v0.42</div>
        <div id="terminal-content"></div>
      </div>

      <!-- 主内容区 -->
      <div id="main-content">
        <div id="terminal-toggle" onclick="toggleTerminal()">
          <svg
            id="toggle-icon-hide"
            xmlns="http://www.w3.org/2000/svg"
            width="24"
            height="24"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
          >
            <polyline points="15 18 9 12 15 6"></polyline>
          </svg>
          <svg
            id="toggle-icon-show"
            xmlns="http://www.w3.org/2000/svg"
            width="24"
            height="24"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            style="display: none"
          >
            <polyline points="9 18 15 12 9 6"></polyline>
          </svg>
        </div>
        <div class="app-container">
          <!-- 主菜单 -->
          <div id="menu-view" class="app-view w-full max-w-4xl p-4">
            <div class="grid grid-cols-2 md:grid-cols-4 gap-6">
              <div class="menu-button" onclick="changeState('tdee-view')">
                <h2 class="text-xl font-bold text-white">TDEE 计算</h2>
                <p class="text-xs mt-2">TDEE</p>
              </div>
              <div
                class="menu-button"
                onclick="changeState('weight-loss-view')"
              >
                <h2 class="text-xl font-bold text-white">减肥目标</h2>
                <p class="text-xs mt-2">Weight Goal</p>
              </div>
              <div class="menu-button" onclick="changeState('date-calc-view')">
                <h2 class="text-xl font-bold text-white">日期计算</h2>
                <p class="text-xs mt-2">Date Calc</p>
              </div>
              <div class="menu-button" onclick="changeState('bmi-view')">
                <h2 class="text-xl font-bold text-white">BMI 计算</h2>
                <p class="text-xs mt-2">BMI Calc</p>
              </div>
            </div>
          </div>

          <!-- 各个计算器模块 -->
          <div id="bmi-view" class="app-view w-full max-w-md p-4">
            <div class="card">
              <h2
                class="text-2xl font-bold text-center text-white mb-4"
                style="font-family: var(--header-font)"
              >
                BMI 计算器
              </h2>
              <div class="space-y-4">
                <div>
                  <label for="bmi_height">身高 (cm)</label
                  ><input type="number" id="bmi_height" />
                </div>
                <div>
                  <label for="bmi_weight">体重 (kg)</label
                  ><input type="number" id="bmi_weight" />
                </div>
              </div>
              <button onclick="calculateBMI()" class="btn mt-4">
                开始计算
              </button>
              <div
                id="bmiResult"
                class="result-box"
                style="display: none"
              ></div>
              <button
                onclick="changeState('menu-view')"
                class="btn btn-secondary mt-4"
              >
                返回主菜单
              </button>
            </div>
          </div>
          <div id="date-calc-view" class="app-view w-full max-w-md p-4">
            <div class="card">
              <h2
                class="text-2xl font-bold text-center text-white mb-4"
                style="font-family: var(--header-font)"
              >
                日期计算器
              </h2>
              <div class="flex rounded-md overflow-hidden mb-4">
                <button
                  id="tab-date-diff"
                  class="tab-button active"
                  onclick="switchDateMode('diff')"
                >
                  日期差距</button
                ><button
                  id="tab-date-countdown"
                  class="tab-button"
                  onclick="switchDateMode('countdown')"
                >
                  倒计时</button
                ><button
                  id="tab-date-op"
                  class="tab-button"
                  onclick="switchDateMode('op')"
                >
                  日期运算
                </button>
              </div>
              <div id="mode-date-diff">
                <div>
                  <label for="dd_startDate">开始日期</label
                  ><input type="date" id="dd_startDate" />
                </div>
                <div class="mt-4">
                  <label for="dd_endDate">结束日期</label
                  ><input type="date" id="dd_endDate" />
                </div>
              </div>
              <div id="mode-date-countdown" style="display: none">
                <div>
                  <label for="dc_targetDate">目标日期</label
                  ><input type="date" id="dc_targetDate" />
                </div>
              </div>
              <div id="mode-date-op" style="display: none">
                <div>
                  <label for="do_startDate">起始日期</label
                  ><input type="date" id="do_startDate" />
                </div>
                <div class="flex items-center gap-2 my-4">
                  <select id="do_operation" class="w-auto">
                    <option value="add">增加</option>
                    <option value="subtract">减少</option></select
                  ><input type="number" id="do_days" placeholder="天数" />
                </div>
              </div>
              <button onclick="calculateDate()" class="btn mt-4">
                开始计算
              </button>
              <div
                id="dateResult"
                class="result-box"
                style="display: none"
              ></div>
              <button
                onclick="changeState('menu-view')"
                class="btn btn-secondary mt-4"
              >
                返回主菜单
              </button>
            </div>
          </div>
          <div id="tdee-view" class="app-view w-full max-w-md p-4">
            <div class="card">
              <h2
                class="text-2xl font-bold text-center text-white mb-4"
                style="font-family: var(--header-font)"
              >
                TDEE 计算器
              </h2>
              <div class="unit-toggle">
                <span
                  id="tdee_unit_kg"
                  class="active"
                  onclick="setTdeeUnit('kg')"
                  >kg</span
                ><span id="tdee_unit_jin" onclick="setTdeeUnit('jin')">斤</span>
              </div>
              <div class="space-y-4">
                <div>
                  <label for="tdee_gender">性别</label
                  ><select id="tdee_gender">
                    <option value="male">男性</option>
                    <option value="female">女性</option>
                  </select>
                </div>
                <div>
                  <label for="tdee_age">年龄 (岁)</label
                  ><input type="number" id="tdee_age" />
                </div>
                <div>
                  <label for="tdee_height">身高 (cm)</label
                  ><input type="number" id="tdee_height" />
                </div>
                <div>
                  <label for="tdee_weight"
                    >体重 (<span class="unit-label">kg</span>)</label
                  ><input type="number" id="tdee_weight" />
                </div>
                <div>
                  <label for="tdee_activity">日常活动等级 (NEAT)</label
                  ><select id="tdee_activity">
                    <option value="1.2">久坐</option>
                    <option value="1.375">轻度</option>
                    <option value="1.55">中度</option>
                    <option value="1.725">高度</option>
                    <option value="1.9">极高</option>
                  </select>
                </div>
                <div>
                  <label for="tdee_eat">额外运动消耗 (EAT, 大卡)</label
                  ><input type="number" id="tdee_eat" />
                </div>
              </div>
              <button onclick="calculateTDEE()" class="btn mt-4">
                计算 TDEE
              </button>
              <div id="tdeeResultReport" class="hidden"></div>
              <div
                id="tdeeResult"
                class="result-box"
                style="display: none"
              ></div>
              <button
                id="tdee_download_btn"
                class="btn btn-secondary mt-2"
                style="display: none"
                onclick="showReportModal('tdee')"
              >
                导出报告</button
              ><button
                onclick="changeState('menu-view')"
                class="btn btn-secondary mt-2"
              >
                返回主菜单
              </button>
            </div>
          </div>
          <div id="weight-loss-view" class="app-view w-full max-w-lg p-4">
            <div class="card">
              <h2
                class="text-2xl font-bold text-center text-white mb-4"
                style="font-family: var(--header-font)"
              >
                减肥目标计算器
              </h2>
              <div>
                <label for="wl_height">身高 (cm)</label
                ><input type="number" id="wl_height" class="mb-4" />
              </div>
              <div class="unit-toggle">
                <span id="wl_unit_kg" onclick="setWeightLossUnit('kg')">kg</span
                ><span
                  id="wl_unit_jin"
                  class="active"
                  onclick="setWeightLossUnit('jin')"
                  >斤</span
                >
              </div>
              <div class="flex rounded-md overflow-hidden mb-4">
                <button
                  id="tab-loss-rate"
                  class="tab-button active"
                  onclick="switchWeightLossMode('rate')"
                >
                  按减重速率</button
                ><button
                  id="tab-calorie-gap"
                  class="tab-button"
                  onclick="switchWeightLossMode('calorie')"
                >
                  按能量缺口
                </button>
              </div>
              <div id="mode-rate" class="space-y-4">
                <div>
                  <label for="wl_currentWeight"
                    >当前体重 (<span class="unit-label">斤</span>)</label
                  ><input type="number" id="wl_currentWeight" />
                </div>
                <div>
                  <label for="wl_targetWeight"
                    >目标体重 (<span class="unit-label">斤</span>)</label
                  ><input type="number" id="wl_targetWeight" />
                </div>
                <div>
                  <label for="wl_weeklyLoss"
                    >每周计划减重 (<span class="unit-label">斤</span>)</label
                  ><input type="number" id="wl_weeklyLoss" />
                </div>
              </div>
              <div id="mode-calorie" class="space-y-4" style="display: none">
                <div>
                  <label for="wc_currentWeight"
                    >当前体重 (<span class="unit-label">斤</span>)</label
                  ><input type="number" id="wc_currentWeight" />
                </div>
                <div>
                  <label for="wc_targetWeight"
                    >目标体重 (<span class="unit-label">斤</span>)</label
                  ><input type="number" id="wc_targetWeight" />
                </div>
                <div>
                  <label for="wc_calorieDeficit">每日能量缺口 (大卡/kcal)</label
                  ><input type="number" id="wc_calorieDeficit" />
                </div>
              </div>
              <button onclick="calculateWeightLossDate()" class="btn mt-4">
                开始计算
              </button>
              <div
                id="weightLossResult"
                class="result-box"
                style="display: none"
              ></div>
              <div class="mt-4"><canvas id="weightLossChart"></canvas></div>
              <!-- V0.42: Container for the UI table -->
              <div
                id="weightLossTableContainer"
                class="mt-4"
                style="display: none"
              ></div>
              <div id="wlResultReport" class="hidden"></div>
              <button
                id="wl_download_btn"
                class="btn btn-secondary mt-2"
                style="display: none"
                onclick="showReportModal('wl')"
              >
                导出报告
              </button>
              <button
                onclick="changeState('menu-view')"
                class="btn btn-secondary mt-4"
              >
                返回主菜单
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 报告模态框 -->
    <div id="report-modal">
      <div class="card w-full max-w-md">
        <h3 class="text-xl font-bold text-center mb-4">生成报告</h3>
        <label for="report-quote">输入你的励志语 (可选)</label
        ><textarea
          id="report-quote"
          rows="3"
          class="w-full p-2 bg-gray-700 rounded-md border border-gray-600"
          placeholder="例如:坚持就是胜利!"
        ></textarea>
        <div class="flex gap-4 mt-4">
          <button onclick="generateReport()" class="btn">生成并下载</button
          ><button onclick="hideReportModal()" class="btn btn-secondary">
            取消
          </button>
        </div>
      </div>
    </div>

    <!-- Aplayer 和 MetingJS 脚本 -->
    <script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/meting@1.2.0/dist/Meting.min.js"></script>

    <!-- 点击特效脚本 -->
    <script src="https://cdn.jsdelivr.net/gh/wallleap/cdn/js/shehuizhuyi.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/wallleap/cdn/js/love.js"></script>

    <script>
      // --- 全局变量 & 初始化 ---
      let currentState = "loading-view";
      let lastCalculationData = {};
      window.onload = () => {
        initLoadingAnimation();
        initParticleAnimation();
        initMatrixRain();
      };
      function changeState(newState) {
        document.getElementById(currentState)?.classList.remove("active");
        document.getElementById(newState)?.classList.add("active");
        currentState = newState;
      }

      // --- 头部互动 ---
      (function () {
        var OriginTitile = document.title,
          titleTime;
        document.addEventListener("visibilitychange", function () {
          if (document.hidden) {
            document.title = "歪,你去哪里了?";
            clearTimeout(titleTime);
          } else {
            document.title = "(つェ⊂)咦,又回来了!";
            titleTime = setTimeout(function () {
              document.title = OriginTitile;
            }, 2000);
          }
        });
      })();

      // --- 开机动画 ---
      function initLoadingAnimation() {
        const container = document.getElementById("loading-view");
        for (let i = 0; i < 15; i++) {
          const shape = document.createElement("div");
          shape.className = "shape";
          shape.style.width = `${Math.random() * 20 + 5}px`;
          shape.style.height = shape.style.width;
          shape.style.left = `${Math.random() * 100}%`;
          shape.style.top = `${Math.random() * 100}%`;
          shape.style.animationDelay = `${Math.random() * 5}s`;
          container.appendChild(shape);
        }
        setTimeout(() => {
          changeState("menu-view");
          printToTerminal(
            [
              {
                text: "欢迎来到个人健康数据中心 v0.42 (*^▽^*)",
                className: "info",
              },
              { text: "系统初始化...[OK]" },
              { text: "所有模块已加载,等待用户指令..." },
            ],
            true
          );
        }, 2500);
      }

      // --- 终端  ---
      const terminalWrapper = document.getElementById("terminal-wrapper");
      const mainContent = document.getElementById("main-content");
      const terminalContent = document.getElementById("terminal-content");
      let typeInterval;
      const alpacaArt = `
* *   ┏┓   ┏┓+ +
*  ┏┛┻━━━┛┻┓ + +
*  ┃       ┃   
*  ┃   ━   ┃ ++ + + +
* ████━████ ┃+
*  ┃       ┃ +
*  ┃   ┻   ┃
*  ┃       ┃ + +
*  ┗━┓   ┏━┛
*    ┃   ┃            
*    ┃   ┃ + + + +
*    ┃   ┃
*    ┃   ┃ +  神兽保佑
*    ┃   ┃    代码无bug   
*    ┃   ┃  +
*    ┃    ┗━━━┓ + +
*    ┃        ┣┓
*    ┃        ┏┛
*    ┗┓┓┏━┳┓┏┛ + + + +
*     ┃┫┫ ┃┫┫
*     ┗┻┛ ┗┻┛+ + + +
`;
      function startIdleAnimation() {
        const existingIdle = document.getElementById("terminal-idle-animation");
        if (existingIdle) return;
        const animationEl = document.createElement("pre");
        animationEl.id = "terminal-idle-animation";
        animationEl.textContent = alpacaArt;
        terminalContent.appendChild(animationEl);
      }
      function printToTerminal(lines, startIdleOnComplete = false) {
        clearInterval(typeInterval);
        terminalContent.innerHTML = "";
        let lineIndex = 0;
        let charIndex = 0;
        function type() {
          if (lineIndex >= lines.length) {
            clearInterval(typeInterval);
            if (startIdleOnComplete) startIdleAnimation();
            return;
          }
          const currentLine = lines[lineIndex];
          if (charIndex === 0) {
            const lineEl = document.createElement("span");
            lineEl.className = `line ${currentLine.className || ""}`;
            terminalContent.appendChild(lineEl);
          }
          const allLineEls = terminalContent.querySelectorAll(".line");
          const targetLineEl = allLineEls[allLineEls.length - 1];
          targetLineEl.textContent = currentLine.text.substring(
            0,
            charIndex + 1
          );
          charIndex++;
          if (charIndex >= currentLine.text.length) {
            charIndex = 0;
            lineIndex++;
          }
          terminalContent.scrollTop = terminalContent.scrollHeight;
        }
        typeInterval = setInterval(type, 30);
      }

      // --- 背景特效  ---
      function initMatrixRain() {
        const canvas = document.getElementById("matrix-canvas");
        const ctx = canvas.getContext("2d");
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        const characters = "01";
        const fontSize = 16;
        const columns = Math.floor(canvas.width / fontSize);
        const drops = Array(columns).fill(1);
        function draw() {
          ctx.fillStyle = "rgba(17, 24, 39, 0.05)";
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          ctx.fillStyle = "#0ea5e9";
          ctx.font = `${fontSize}px Fira Code`;
          for (let i = 0; i < drops.length; i++) {
            const text = characters.charAt(
              Math.floor(Math.random() * characters.length)
            );
            ctx.fillText(text, i * fontSize, drops[i] * fontSize);
            if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
              drops[i] = 0;
            }
            drops[i]++;
          }
        }
        setInterval(draw, 40);
        window.addEventListener("resize", () => {
          canvas.width = window.innerWidth;
          canvas.height = window.innerHeight;
          drops.length = Math.floor(canvas.width / fontSize);
          drops.fill(1);
        });
      }
      function initParticleAnimation() {
        const canvas = document.getElementById("bg-canvas");
        const ctx = canvas.getContext("2d");
        let particles = [];
        const particleCount = 80;
        const connectDistance = 120;
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        class Particle {
          constructor() {
            this.x = Math.random() * canvas.width;
            this.y = Math.random() * canvas.height;
            this.size = Math.random() * 2 + 1;
            this.speedX = Math.random() * 0.5 - 0.25;
            this.speedY = Math.random() * 0.5 - 0.25;
          }
          update() {
            if (this.x > canvas.width || this.x < 0) this.speedX *= -1;
            if (this.y > canvas.height || this.y < 0) this.speedY *= -1;
            this.x += this.speedX;
            this.y += this.speedY;
          }
          draw() {
            ctx.fillStyle = "rgba(14, 165, 233, 0.8)";
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            ctx.fill();
          }
        }
        function initParticles() {
          for (let i = 0; i < particleCount; i++)
            particles.push(new Particle());
        }
        function connectParticles() {
          for (let a = 0; a < particles.length; a++) {
            for (let b = a; b < particles.length; b++) {
              const distance = Math.sqrt(
                Math.pow(particles[a].x - particles[b].x, 2) +
                  Math.pow(particles[a].y - particles[b].y, 2)
              );
              if (distance < connectDistance) {
                ctx.strokeStyle = `rgba(14, 165, 233, ${
                  1 - distance / connectDistance
                })`;
                ctx.lineWidth = 0.5;
                ctx.beginPath();
                ctx.moveTo(particles[a].x, particles[a].y);
                ctx.lineTo(particles[b].x, particles[b].y);
                ctx.stroke();
              }
            }
          }
        }
        function animate() {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          particles.forEach((p) => {
            p.update();
            p.draw();
          });
          connectParticles();
          requestAnimationFrame(animate);
        }
        initParticles();
        animate();
        window.addEventListener("resize", () => {
          canvas.width = window.innerWidth;
          canvas.height = window.innerHeight;
          particles = [];
          initParticles();
        });
      }

      // --- 报告系统 ---
      const reportModal = document.getElementById("report-modal");
      let currentReportType = "";
      function showReportModal(type) {
        currentReportType = type;
        reportModal.style.display = "flex";
      }
      function hideReportModal() {
        reportModal.style.display = "none";
      }
      function generateReport() {
        const quote = document.getElementById("report-quote").value;
        const timestamp = new Date().toLocaleString("zh-CN");
        const data = lastCalculationData[currentReportType];
        if (!data) return;
        let inputsHTML = Object.entries(data.inputs)
          .map(
            ([key, value]) =>
              `<tr><td class="font-semibold">${key}</td><td>${value}</td></tr>`
          )
          .join("");
        let progressHTML = "";
        if (data.progress) {
          progressHTML = `<h3 class="text-lg font-bold text-sky-400 mt-4">进度预测</h3><table class="data-table"><thead><tr><th>天数</th><th>日期</th><th>体重</th><th>BMI</th></tr></thead><tbody>${data.progress
            .map(
              (p) =>
                `<tr><td>${p.day}</td><td>${p.date}</td><td>${p.weightKg} kg (${p.weightJin} 斤)</td><td>${p.bmi}</td></tr>`
            )
            .join("")}</tbody></table>`;
        }
        let sourceEl, resultHTML;
        if (currentReportType === "tdee") {
          sourceEl = document.getElementById("tdeeResultReport");
          resultHTML = document.getElementById("tdeeResult").innerHTML;
        } else if (currentReportType === "wl") {
          sourceEl = document.getElementById("wlResultReport");
          const chartImage = document
            .getElementById("weightLossChart")
            .toDataURL("image/png");
          resultHTML =
            document.getElementById("weightLossResult").innerHTML +
            `<img src="${chartImage}" class="mt-4 rounded-lg" />`;
        }
        sourceEl.innerHTML = `<div class="p-6 bg-gray-800 text-white rounded-lg border border-sky-500"><h2 class="text-2xl font-bold text-sky-400 mb-4" style="font-family: var(--header-font);">健康数据报告</h2><h3 class="text-lg font-bold text-sky-400">输入参数</h3><table class="data-table">${inputsHTML}</table><h3 class="text-lg font-bold text-sky-400 mt-4">计算结果</h3><div class="result-box !mt-0">${resultHTML}</div>${progressHTML}${
          quote
            ? `<div class="mt-4 p-4 border-l-4 border-sky-500 bg-gray-700 italic">"${quote}"</div>`
            : ""
        }<p class="text-right text-xs text-gray-400 mt-4">${timestamp}</p></div>`;
        sourceEl.classList.remove("hidden");
        html2canvas(sourceEl, { backgroundColor: "#1f2937", scale: 2 }).then(
          (canvas) => {
            const link = document.createElement("a");
            link.download = `report-${currentReportType}-${Date.now()}.jpg`;
            link.href = canvas.toDataURL("image/jpeg", 0.9);
            link.click();
            sourceEl.classList.add("hidden");
            sourceEl.innerHTML = "";
          }
        );
        hideReportModal();
      }

      // --- 减肥计算器 ---
      let weightLossChartInstance;
      function calculateWeightLossDate() {
        const resultEl = document.getElementById("weightLossResult");
        const tableContainer = document.getElementById(
          "weightLossTableContainer"
        );
        const toKg = (val) => (wl_unit === "jin" ? val / 2 : val);
        let daysRequired, startWeightKg, targetKg, inputs;

        const height = parseFloat(document.getElementById("wl_height").value);
        if (isNaN(height) || height <= 0) {
          printToTerminal(
            [
              {
                text: "[ERROR] 请在减肥目标计算器中输入有效的身高(cm)。",
                className: "warn",
              },
            ],
            true
          );
          return;
        }
        const heightM = height / 100;

        if (weightLossMode === "rate") {
          const current = parseFloat(
            document.getElementById("wl_currentWeight").value
          );
          const target = parseFloat(
            document.getElementById("wl_targetWeight").value
          );
          const weeklyLoss = parseFloat(
            document.getElementById("wl_weeklyLoss").value
          );
          startWeightKg = toKg(current);
          targetKg = toKg(target);
          let weeklyLossKg = toKg(weeklyLoss);
          if (
            isNaN(startWeightKg) ||
            isNaN(targetKg) ||
            isNaN(weeklyLossKg) ||
            weeklyLossKg <= 0 ||
            startWeightKg <= targetKg
          ) {
            return;
          }
          daysRequired = Math.ceil(
            ((startWeightKg - targetKg) / weeklyLossKg) * 7
          );
          inputs = {
            身高: `${height} cm`,
            当前体重: `${current} ${wl_unit}`,
            目标体重: `${target} ${wl_unit}`,
            每周减重: `${weeklyLoss} ${wl_unit}`,
          };
        } else {
          const current = parseFloat(
            document.getElementById("wc_currentWeight").value
          );
          const target = parseFloat(
            document.getElementById("wc_targetWeight").value
          );
          const deficit = parseFloat(
            document.getElementById("wc_calorieDeficit").value
          );
          startWeightKg = toKg(current);
          targetKg = toKg(target);
          if (
            isNaN(startWeightKg) ||
            isNaN(targetKg) ||
            isNaN(deficit) ||
            deficit <= 0 ||
            startWeightKg <= targetKg
          ) {
            return;
          }
          daysRequired = Math.ceil(
            ((startWeightKg - targetKg) * 7700) / deficit
          );
          inputs = {
            身高: `${height} cm`,
            当前体重: `${current} ${wl_unit}`,
            目标体重: `${target} ${wl_unit}`,
            每日能量缺口: `${deficit} kcal`,
          };
        }

        const targetDate = new Date();
        targetDate.setDate(targetDate.getDate() + daysRequired);
        const targetDateFormatted = targetDate.toISOString().split("T")[0];
        resultEl.innerHTML = `预计需要 <strong class="text-sky-400">${daysRequired}</strong> 天, <br>将在 <strong class="text-sky-400">${targetDateFormatted}</strong> 左右达成目标。`;
        resultEl.style.display = "block";
        document.getElementById("wl_download_btn").style.display = "block";

        const weightLossPerDay = (startWeightKg - targetKg) / daysRequired;
        const labels = [],
          data = [],
          progressLog = [];
        const terminalLines = [
          {
            text: ">> system.run(module.Weight_Projection)",
            className: "info",
          },
        ];

        for (let i = 0; i <= 10; i++) {
          const progressDay = Math.round(daysRequired * (i / 10));
          const checkpointDate = new Date();
          checkpointDate.setDate(checkpointDate.getDate() + progressDay);
          const formattedDate = checkpointDate.toISOString().split("T")[0];
          const currentWeightKg =
            startWeightKg - weightLossPerDay * progressDay;
          const currentWeightJin = currentWeightKg * 2;
          const bmi = (currentWeightKg / (heightM * heightM)).toFixed(1);
          progressLog.push({
            day: progressDay,
            date: formattedDate,
            weightKg: currentWeightKg.toFixed(1),
            weightJin: currentWeightJin.toFixed(1),
            bmi: bmi,
          });
          terminalLines.push({
            text: `>  [DAY ${progressDay} | ${formattedDate}] 预测体重: ${currentWeightKg.toFixed(
              1
            )} kg (${currentWeightJin.toFixed(1)} 斤), BMI: ${bmi}`,
          });
        }
        lastCalculationData.wl = { inputs, progress: progressLog };
        labels.push(...progressLog.map((p) => `D${p.day}`));
        data.push(...progressLog.map((p) => p.weightKg));
        terminalLines.push({
          text: `>  [SUCCESS] 预测完成,图表已生成!`,
          className: "success",
        });
        terminalLines.push({ text: ">> 模块运行结束。" });
        printToTerminal(terminalLines, true);

        // 展示表格UI界面
        let tableHTML = `<h3 class="text-lg font-bold text-sky-400 mb-2">进度预测</h3><table class="data-table"><thead><tr><th>天数</th><th>日期</th><th>体重</th><th>BMI</th></tr></thead><tbody>`;
        progressLog.forEach((p) => {
          tableHTML += `<tr><td>${p.day}</td><td>${p.date}</td><td>${p.weightKg} kg (${p.weightJin} 斤)</td><td>${p.bmi}</td></tr>`;
        });
        tableHTML += "</tbody></table>";
        tableContainer.innerHTML = tableHTML;
        tableContainer.style.display = "block";

        const ctx = document.getElementById("weightLossChart").getContext("2d");
        if (weightLossChartInstance) weightLossChartInstance.destroy();
        weightLossChartInstance = new Chart(ctx, {
          type: "line",
          data: {
            labels,
            datasets: [
              {
                label: "体重 (kg)",
                data,
                borderColor: "rgb(14, 165, 233)",
                backgroundColor: "rgba(14, 165, 233, 0.2)",
                fill: true,
                tension: 0.3,
              },
            ],
          },
          options: {
            scales: {
              y: { beginAtZero: false, ticks: { color: "#9ca3af" } },
              x: { ticks: { color: "#9ca3af" } },
            },
            plugins: { legend: { labels: { color: "#9ca3af" } } },
          },
        });
      }

      // --- 其他模块的JS代码 ---
      function toggleTerminal() {
        terminalWrapper.classList.toggle("hidden");
        mainContent.classList.toggle("full-width");
        document.getElementById("toggle-icon-hide").style.display =
          terminalWrapper.classList.contains("hidden") ? "none" : "block";
        document.getElementById("toggle-icon-show").style.display =
          terminalWrapper.classList.contains("hidden") ? "block" : "none";
      }
      function calculateBMI() {
        const height = parseFloat(document.getElementById("bmi_height").value);
        const weight = parseFloat(document.getElementById("bmi_weight").value);
        const resultEl = document.getElementById("bmiResult");
        const script = [
          { text: ">> system.run(module.BMI_Calculator)", className: "info" },
          { text: `>  用户数据已捕获...` },
          { text: `>  身高参数: ${height} cm`, className: "data" },
          { text: `>  体重参数: ${weight} kg`, className: "data" },
        ];
        if (isNaN(height) || isNaN(weight) || height <= 0 || weight <= 0) {
          script.push({
            text: "[ERROR] 输入数据无效,计算中止。",
            className: "warn",
          });
          printToTerminal(script, true);
          resultEl.innerHTML = "请输入有效的身高和体重。";
          resultEl.style.display = "block";
          return;
        }
        script.push(
          { text: ">  正在载入核心计算公式: [weight / (height/100)^2]..." },
          { text: ">  计算中..." }
        );
        const bmi = (weight / Math.pow(height / 100, 2)).toFixed(2);
        let category = "";
        if (bmi < 18.5) category = "体重过轻";
        else if (bmi < 24) category = "正常范围";
        else if (bmi < 28) category = "超重";
        else category = "肥胖";
        script.push({
          text: `>  计算完毕... BMI值: ${bmi}`,
          className: "success",
        });
        script.push({ text: `>  分析结果: ${category}`, className: "success" });
        script.push({ text: ">> 模块运行结束。" });
        printToTerminal(script, true);
        resultEl.innerHTML = `您的BMI是 <strong class="text-sky-400 text-xl">${bmi}</strong>, 属于 <strong class="text-sky-400">${category}</strong> 范围。`;
        resultEl.style.display = "block";
      }
      let dateMode = "diff";
      function switchDateMode(mode) {
        dateMode = mode;
        ["diff", "countdown", "op"].forEach((m) => {
          document.getElementById(`mode-date-${m}`).style.display =
            m === mode ? "block" : "none";
          document
            .getElementById(`tab-date-${m}`)
            .classList.toggle("active", m === mode);
        });
        document.getElementById("dateResult").style.display = "none";
      }
      function calculateDate() {
        const resultEl = document.getElementById("dateResult");
        let resultText = "";
        if (dateMode === "diff") {
          const start = document.getElementById("dd_startDate").value;
          const end = document.getElementById("dd_endDate").value;
          if (!start || !end) {
            resultEl.innerHTML = "请选择两个日期";
            resultEl.style.display = "block";
            return;
          }
          const diff = Math.round(
            Math.abs(new Date(end) - new Date(start)) / (1000 * 60 * 60 * 24)
          );
          resultText = `两个日期相差 <strong class="text-sky-400">${diff}</strong> 天`;
        } else if (dateMode === "countdown") {
          const target = document.getElementById("dc_targetDate").value;
          if (!target) {
            resultEl.innerHTML = "请选择目标日期";
            resultEl.style.display = "block";
            return;
          }
          const today = new Date();
          today.setHours(0, 0, 0, 0);
          const diff = Math.round(
            (new Date(target) - today) / (1000 * 60 * 60 * 24)
          );
          resultText =
            diff >= 0
              ? `距离目标还有 <strong class="text-sky-400">${diff}</strong> 天`
              : `目标已过去 <strong class="text-yellow-400">${-diff}</strong> 天`;
        } else {
          const start = document.getElementById("do_startDate").value;
          const days = parseInt(document.getElementById("do_days").value);
          const op = document.getElementById("do_operation").value;
          if (!start || isNaN(days)) {
            resultEl.innerHTML = "请输入有效日期和天数";
            resultEl.style.display = "block";
            return;
          }
          const newDate = new Date(start);
          newDate.setDate(newDate.getDate() + (op === "add" ? days : -days));
          resultText = `计算结果: <strong class="text-sky-400">${
            newDate.toISOString().split("T")[0]
          }</strong>`;
        }
        resultEl.innerHTML = resultText;
        resultEl.style.display = "block";
        printToTerminal(
          [{ text: "[SUCCESS] 日期计算完成。", className: "success" }],
          true
        );
      }
      function calculateTDEE(isRecalculation = false) {
        const resultEl = document.getElementById("tdeeResult");
        let bmr, neat, eat, tdee, inputs;
        const script = [
          { text: ">> system.run(module.TDEE_Calculator)", className: "info" },
        ];
        if (isRecalculation) {
          bmr = parseFloat(document.getElementById("editable_bmr").value);
          neat = parseFloat(document.getElementById("editable_neat").value);
          eat = parseFloat(document.getElementById("editable_eat").value);
          if (isNaN(bmr) || isNaN(neat) || isNaN(eat)) {
            return;
          }
          script.push({ text: ">  接收到手动调整参数...", className: "data" });
          tdee = bmr + neat + eat;
          script.push({
            text: `>  重新计算... BMR+NEAT+EAT = ${tdee.toFixed(0)}`,
            className: "success",
          });
          inputs = lastCalculationData.tdee.inputs;
        } else {
          const gender = document.getElementById("tdee_gender").value;
          const age = parseInt(document.getElementById("tdee_age").value);
          const height = parseFloat(
            document.getElementById("tdee_height").value
          );
          let weight = parseFloat(document.getElementById("tdee_weight").value);
          const activity = parseFloat(
            document.getElementById("tdee_activity").value
          );
          eat = parseFloat(document.getElementById("tdee_eat").value) || 0;
          if (isNaN(age) || isNaN(height) || isNaN(weight)) {
            return;
          }
          let displayWeight = weight;
          if (tdee_unit === "jin") weight /= 2;
          if (gender === "male") {
            bmr = 10 * weight + 6.25 * height - 5 * age + 5;
          } else {
            bmr = 10 * weight + 6.25 * height - 5 * age - 161;
          }
          neat = bmr * (activity - 1);
          tdee = bmr + neat + eat;
          inputs = {
            性别: gender,
            年龄: age,
            "身高(cm)": height,
            体重: `${displayWeight} ${tdee_unit}`,
            活动等级: activity,
            EAT: eat,
          };
          script.push({
            text: `>  BMR计算完成: ${bmr.toFixed(0)} kcal`,
            className: "success",
          });
          script.push({
            text: `>  NEAT计算完成: ${neat.toFixed(0)} kcal`,
            className: "success",
          });
          script.push({
            text: `>  总消耗TDEE计算完成: ${tdee.toFixed(0)} kcal`,
            className: "success",
          });
        }
        lastCalculationData.tdee = {
          inputs,
          results: { bmr, neat, eat, tdee },
        };
        script.push({ text: ">> 模块运行结束。" });
        printToTerminal(script, true);
        resultEl.innerHTML = `<div class="p-2"><p class="text-sm text-gray-400">每日总能量消耗 (TDEE)</p><p class="text-3xl font-bold text-sky-400 my-2">${Math.round(
          tdee
        )} kcal</p><div class="text-left mt-4 text-sm space-y-2"><div class="flex items-center gap-2"><label class="w-28" for="editable_bmr">基础代谢 (BMR):</label><input type="number" id="editable_bmr" value="${Math.round(
          bmr
        )}"></div><div class="flex items-center gap-2"><label class="w-28" for="editable_neat">日常消耗 (NEAT):</label><input type="number" id="editable_neat" value="${Math.round(
          neat
        )}"></div><div class="flex items-center gap-2"><label class="w-28" for="editable_eat">运动消耗 (EAT):</label><input type="number" id="editable_eat" value="${Math.round(
          eat
        )}"></div></div><button onclick="calculateTDEE(true)" class="btn btn-secondary mt-4 text-xs">重新计算 TDEE</button></div>`;
        resultEl.style.display = "block";
        document.getElementById("tdee_download_btn").style.display = "block";
      }
      let wl_unit = "jin";
      function setWeightLossUnit(unit) {
        wl_unit = unit;
        document
          .querySelectorAll("#weight-loss-view .unit-label")
          .forEach((el) => (el.textContent = unit));
        document
          .getElementById("wl_unit_kg")
          .classList.toggle("active", unit === "kg");
        document
          .getElementById("wl_unit_jin")
          .classList.toggle("active", unit === "jin");
      }
      let weightLossMode = "rate";
      function switchWeightLossMode(mode) {
        weightLossMode = mode;
        document.getElementById("mode-rate").style.display =
          mode === "rate" ? "block" : "none";
        document.getElementById("mode-calorie").style.display =
          mode === "calorie" ? "block" : "none";
        document
          .getElementById("tab-loss-rate")
          .classList.toggle("active", mode === "rate");
        document
          .getElementById("tab-calorie-gap")
          .classList.toggle("active", mode === "calorie");
        document.getElementById("weightLossResult").style.display = "none";
      }
      let tdee_unit = "kg";
      function setTdeeUnit(unit) {
        tdee_unit = unit;
        document
          .querySelectorAll("#tdee-view .unit-label")
          .forEach((el) => (el.textContent = unit));
        document
          .getElementById("tdee_unit_kg")
          .classList.toggle("active", unit === "kg");
        document
          .getElementById("tdee_unit_jin")
          .classList.toggle("active", unit === "jin");
      }
    </script>
  </body>
</html>

posted @ 2025-09-28 14:42  舟清颺  阅读(9)  评论(0)    收藏  举报