chore: 初始提交 - 移除所有硬编码凭据,统一从环境变量读取
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"_comment": "健身日志工具的前端鉴权配置",
|
||||
"enable_auth_comment": "true:启用鉴权;false:暂时对所有访问者开放(无登录限制)",
|
||||
"enable_auth": true,
|
||||
"max_age_days_comment": "鉴权 Cookie 有效期(天),范围建议 1~365",
|
||||
"max_age_days": 30,
|
||||
"cookieName_comment": "鉴权 Cookie 名称,建议保持默认",
|
||||
"cookieName": "fitness_diary_gate",
|
||||
"guidParam_comment": "URL 中的 GUID 参数名,建议使用小写 guid",
|
||||
"guidParam": "guid",
|
||||
"guidValue_comment": "GUID 参数值,建议使用高强度随机长串并定期更换",
|
||||
"guidValue": "F1112aD-CH11ANGE-Ts2s2sO-YW21OUR-Ls1weONG-GU4ffeID"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
@@ -0,0 +1,355 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>运动日志 | Fitness Diary</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div class="tool-tabs">
|
||||
<button class="tab-btn active" data-tab="records">记录</button>
|
||||
<button class="tab-btn" data-tab="weekly">本周剩余</button>
|
||||
<button class="tab-btn" data-tab="calendar">日历</button>
|
||||
<button class="tab-btn" data-tab="stats">统计</button>
|
||||
<button class="tab-btn" data-tab="screen">运动大屏</button>
|
||||
<button class="tab-btn" data-tab="settings">设置</button>
|
||||
</div>
|
||||
|
||||
<section id="section-records" class="tab-content active">
|
||||
<div class="stats-cards">
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #00a8ff 0%, #4cdfff 100%);">
|
||||
<div class="stat-label">本周总千卡</div>
|
||||
<div class="stat-value" id="stat-calories">0</div>
|
||||
<div class="stat-icon">🔥 运动能量</div>
|
||||
</div>
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #00d8a7 0%, #00e6b8 100%);">
|
||||
<div class="stat-label">运动时长</div>
|
||||
<div class="stat-value" id="stat-duration">0<span style="font-size: 16px;">分钟</span></div>
|
||||
<div class="stat-icon">⏱️ 坚持时间</div>
|
||||
</div>
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #ff9f43 0%, #ffb74d 100%);">
|
||||
<div class="stat-label">站立次数</div>
|
||||
<div class="stat-value" id="stat-stand">0</div>
|
||||
<div class="stat-icon">🔄 活动频率</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>🏃♀️ 已记录数据</h3>
|
||||
<div class="controls" style="display: flex; gap: 10px;">
|
||||
<button id="btn-add-modal" class="primary">📝 记一笔</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-bar filter-wrap">
|
||||
<div class="filter-group">
|
||||
<label class="mobile-label">📅 按日期筛选</label>
|
||||
<div class="filter-row">
|
||||
<input type="date" id="filter-start" class="mobile-input">
|
||||
<span class="range-sep">至</span>
|
||||
<input type="date" id="filter-end" class="mobile-input">
|
||||
<button id="btn-filter" class="secondary btn-sm">筛选</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-actions-right">
|
||||
<button id="btn-prev-week" class="secondary btn-sm">◀ 上周</button>
|
||||
<button id="btn-this-week" class="primary btn-sm">本周</button>
|
||||
<button id="btn-next-week" class="secondary btn-sm">下周 ▶</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>日期</th>
|
||||
<th>每日计划</th>
|
||||
<th>活动千卡</th>
|
||||
<th>时长(分)</th>
|
||||
<th>站立</th>
|
||||
<th>运动项目明细</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="record-list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="weekly-must-warning" class="weekly-warning" style="display:none"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="section-weekly" class="tab-content">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>本周达标剩余</h3>
|
||||
<div class="muted" id="weekly-range"></div>
|
||||
</div>
|
||||
<div class="grid-2" id="weekly-progress"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="section-calendar" class="tab-content">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>📅 运动日历</h3>
|
||||
<div class="controls" style="display:flex;gap:8px;">
|
||||
<button id="btn-prev-month" class="secondary">◀ 上一月</button>
|
||||
<button id="btn-next-month" class="secondary">下一月 ▶</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-wrapper">
|
||||
<div class="calendar-header" id="calendar-title"></div>
|
||||
<table class="calendar">
|
||||
<thead><tr><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th><th>日</th></tr></thead>
|
||||
<tbody id="calendar-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="section-stats" class="tab-content">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>查询统计</h3>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<div class="stats-filter-grid">
|
||||
<label class="mobile-label">起始日期</label>
|
||||
<input type="date" id="stats-start" class="mobile-input">
|
||||
<label class="mobile-label">结束日期</label>
|
||||
<input type="date" id="stats-end" class="mobile-input">
|
||||
<button id="btn-stats" class="primary btn-sm">统计</button>
|
||||
<button id="btn-export" class="secondary btn-sm">导出Excel</button>
|
||||
</div>
|
||||
<div class="quick-range">
|
||||
<button type="button" id="s-prev-week" class="range-btn">上周</button>
|
||||
<button type="button" id="s-this-week" class="range-btn">本周</button>
|
||||
<button type="button" id="s-next-week" class="range-btn">下周</button>
|
||||
<span style="opacity:.6;margin:0 8px;">|</span>
|
||||
<button type="button" id="s-prev-month" class="range-btn">上月</button>
|
||||
<button type="button" id="s-this-month" class="range-btn">本月</button>
|
||||
<button type="button" id="s-next-month" class="range-btn">下月</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-cards">
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #00a8ff 0%, #4cdfff 100%);">
|
||||
<div class="stat-label">总千卡</div>
|
||||
<div class="stat-value" id="stats-total-cal">0</div>
|
||||
<div class="stat-icon">🔥 运动能量</div>
|
||||
</div>
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #00d8a7 0%, #00e6b8 100%);">
|
||||
<div class="stat-label">总时长(分钟)</div>
|
||||
<div class="stat-value" id="stats-total-dur">0</div>
|
||||
<div class="stat-icon">⏱️ 坚持时间</div>
|
||||
</div>
|
||||
<div class="stat-card" style="background: linear-gradient(135deg, #ff9f43 0%, #ffb74d 100%);">
|
||||
<div class="stat-label">总站立次数</div>
|
||||
<div class="stat-value" id="stats-total-stand">0</div>
|
||||
<div class="stat-icon">🔄 活动频率</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-2">
|
||||
<div class="chart-container">
|
||||
<h3>记录频率</h3>
|
||||
<canvas id="pieDays" height="200"></canvas>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<h3>每周汇总</h3>
|
||||
<canvas id="barWeekly" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-container">
|
||||
<h3>记录明细(所选范围)</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>日期</th><th>计划</th><th>千卡</th><th>时长</th><th>站立</th><th>项目数</th></tr></thead>
|
||||
<tbody id="stats-records"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="section-screen" class="tab-content">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>🏃♂️ 运动大屏</h3>
|
||||
</div>
|
||||
<div class="grid-3">
|
||||
<div style="display:flex;flex-direction:column;gap:16px;">
|
||||
<div class="screen-card">
|
||||
<div class="label">📈 本周千卡趋势</div>
|
||||
<canvas id="lineCal" height="160"></canvas>
|
||||
</div>
|
||||
<div class="screen-card">
|
||||
<div class="label">⏰ 本周时长趋势</div>
|
||||
<canvas id="lineDur" height="160"></canvas>
|
||||
</div>
|
||||
<div class="screen-card">
|
||||
<div class="label">🚶♀️ 本周站立趋势</div>
|
||||
<canvas id="lineStand" height="160"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:16px;">
|
||||
<div class="screen-card">
|
||||
<div class="label">🎯 项目构成(本周数量)</div>
|
||||
<canvas id="pieComp" height="300"></canvas>
|
||||
</div>
|
||||
<div class="screen-card">
|
||||
<div class="label">📅 月度趋势</div>
|
||||
<canvas id="barMonthly" height="220"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="screen-card">
|
||||
<div class="label">🎯 每周目标进度</div>
|
||||
<div class="progress-list" id="weekly-progress-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="section-settings" class="tab-content">
|
||||
<div class="card">
|
||||
<div class="card-header"><h3>运动项目管理与每周达标设置</h3></div>
|
||||
<div class="table-responsive">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>项目</th><th>单位</th><th>每周目标</th><th>排序</th><th>操作</th></tr></thead>
|
||||
<tbody id="settings-types"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;margin-top:12px;">
|
||||
<button id="btn-save-types" class="primary">保存设置</button>
|
||||
</div>
|
||||
<h3 style="margin-top:20px;">新增运动项目</h3>
|
||||
<div class="grid-3">
|
||||
<div><label>项目名称</label><input type="text" id="add-type-name"></div>
|
||||
<div><label>单位</label><input type="text" id="add-type-unit"></div>
|
||||
<div><label>每周目标</label><input type="number" id="add-type-goal" value="0"></div>
|
||||
<div style="display:flex;align-items:flex-end;"><button id="btn-add-type" class="secondary">新增项目</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><h3>本日计划管理</h3></div>
|
||||
<div class="table-responsive">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>计划名称</th><th>操作</th></tr></thead>
|
||||
<tbody id="settings-plans"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="display:flex;justify-content:flex-end;margin-top:12px;">
|
||||
<button id="btn-save-plans" class="primary">保存计划</button>
|
||||
</div>
|
||||
<h3 style="margin-top:20px;">新增本日计划</h3>
|
||||
<div class="grid-2">
|
||||
<div><label>计划名称</label><input type="text" id="add-plan-name"></div>
|
||||
<div style="display:flex;align-items:flex-end;"><button id="btn-add-plan" class="secondary">新增计划</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑 模态框 -->
|
||||
<div id="modal-form" class="modal">
|
||||
<div class="modal-content">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||||
<h3 style="margin: 0;">📝 记录运动</h3>
|
||||
<button id="btn-close-modal" style="background: none; border: none; font-size: 24px; cursor: pointer;">×</button>
|
||||
</div>
|
||||
|
||||
<form id="record-form">
|
||||
<div style="margin-bottom: 16px;">
|
||||
<label>日期</label>
|
||||
<input type="date" name="record_date" required style="width: 100%;">
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 16px;">
|
||||
<label>每日计划</label>
|
||||
<select name="daily_plan_id" id="daily-plan-select" style="width: 100%;">
|
||||
<option value="">加载中...</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; margin-bottom: 16px;">
|
||||
<div>
|
||||
<label>活动千卡</label>
|
||||
<input type="number" name="calories" value="0" style="width: 100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label>运动时长(分)</label>
|
||||
<input type="number" name="exercise_duration" value="0" style="width: 100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label>站立次数</label>
|
||||
<input type="number" name="stand_count" value="0" style="width: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 16px;">
|
||||
<label>运动项目明细 <button type="button" id="add-item-btn" class="secondary" style="padding: 4px 8px; font-size: 12px; margin-left: 8px;">+ 添加项目</button></label>
|
||||
<div id="items-container"></div>
|
||||
</div>
|
||||
|
||||
<div class="health-metrics-grid" style="display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; gap: 12px; margin-bottom: 20px; padding-top: 16px; border-top: 1px dashed #eee;">
|
||||
<div>
|
||||
<label>舒张压(mmHg)</label>
|
||||
<input type="number" name="diastolic_bp" min="1" step="1" style="width: 100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label>收缩压(mmHg)</label>
|
||||
<input type="number" name="systolic_bp" min="1" step="1" style="width: 100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label>心率(bpm)</label>
|
||||
<input type="number" name="heart_rate" min="1" step="1" style="width: 100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label>腰围(cm)</label>
|
||||
<input type="number" name="waist_circ" min="1" step="1" style="width: 100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label>体重(kg)</label>
|
||||
<input type="number" name="weight_kg" min="1" step="0.1" style="width: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="primary" style="width: 100%; padding: 14px;">保存记录</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="record-detail-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;">
|
||||
<h3 style="margin:0;">记录详情</h3>
|
||||
<button id="btn-close-detail" style="background:none;border:none;font-size:24px;cursor:pointer;">×</button>
|
||||
</div>
|
||||
<div id="record-detail-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Waiting Box Modal -->
|
||||
<div id="waiting-modal" class="modal" style="z-index: 200;">
|
||||
<div class="modal-content" style="max-width: 400px;">
|
||||
<h3 id="waiting-title" style="margin-top:0; border-bottom: 2px solid var(--primary); padding-bottom: 10px;">处理中...</h3>
|
||||
<div id="waiting-steps" class="waiting-steps"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Templates -->
|
||||
<template id="item-template">
|
||||
<div class="item-row">
|
||||
<select class="item-type-select" style="flex: 2;">
|
||||
<option value="">选择项目...</option>
|
||||
</select>
|
||||
<input type="number" class="item-quantity" placeholder="数量" style="flex: 1;">
|
||||
<span class="item-unit unit">次</span>
|
||||
<button type="button" class="danger btn-remove" style="padding: 8px;">×</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,386 @@
|
||||
/* 活力运动风格:清爽蓝/绿/橙系配色方案 */
|
||||
:root{
|
||||
/* 主色调:清爽蓝色系 */
|
||||
--primary: #00a8ff; /* 活力蓝 */
|
||||
--primary-light: #4cdfff; /* 浅蓝 */
|
||||
--primary-dark: #0077cc; /* 深蓝 */
|
||||
|
||||
/* 辅助色:绿色和橙色系 */
|
||||
--accent-green: #00d8a7; /* 活力绿 */
|
||||
--accent-orange: #ff9f43; /* 活力橙 */
|
||||
--accent-yellow: #feca57; /* 阳光黄 */
|
||||
|
||||
/* 中性色 */
|
||||
--secondary: #4a4a4a; /* 深灰 */
|
||||
--danger: #ff6b6b; /* 活力红 */
|
||||
--success: #00d8a7; /* 成功绿 */
|
||||
--warning: #ff9f43; /* 警告橙 */
|
||||
|
||||
/* 背景与表面 */
|
||||
--bg: #f8fafc; /* 浅灰背景 */
|
||||
--surface: #ffffff; /* 白色表面 */
|
||||
--border: #e1e8ed; /* 浅灰边框 */
|
||||
--hover: #f0f7ff; /* 悬停蓝色 */
|
||||
|
||||
/* 文字色 */
|
||||
--text-primary: #2c3e50; /* 深蓝灰 */
|
||||
--text-secondary: #7f8c8d; /* 中灰 */
|
||||
--text-muted: #95a5a6; /* 浅灰 */
|
||||
}
|
||||
|
||||
*{ box-sizing:border-box; }
|
||||
body{ margin:0; font-family:'PingFang SC', 'Helvetica Neue', Arial, sans-serif; background:var(--bg); color:var(--text-primary); line-height:1.6; }
|
||||
|
||||
/* 顶部导航(运动风格) */
|
||||
.nav{
|
||||
display:flex; justify-content:space-between; align-items:center;
|
||||
padding:16px 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--accent-green) 100%);
|
||||
color:white;
|
||||
box-shadow: 0 4px 20px rgba(0,168,255,0.15);
|
||||
position:sticky; top:0; z-index:10;
|
||||
}
|
||||
.nav-left{
|
||||
font-weight:700; font-size:20px;
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.nav a{ text-decoration:none; }
|
||||
.nav-right{
|
||||
display:flex; flex-wrap:nowrap;
|
||||
overflow-x:auto; -webkit-overflow-scrolling:touch;
|
||||
background: rgba(255,255,255,0.15);
|
||||
border-radius: 25px;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-right::-webkit-scrollbar{ display:none; }
|
||||
.nav-right a{
|
||||
position:relative; margin:0 2px;
|
||||
padding:8px 16px;
|
||||
color:rgba(255,255,255,0.9);
|
||||
text-decoration:none;
|
||||
border-radius:20px;
|
||||
transition:all 0.3s ease;
|
||||
font-weight:500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-right a:hover{
|
||||
color:white;
|
||||
background:rgba(255,255,255,0.2);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.nav-right a.active{
|
||||
color:var(--primary);
|
||||
background:white;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.container{ max-width:1000px; margin:24px auto; padding:0 20px; }
|
||||
|
||||
/* 通用控件 - 运动风格 */
|
||||
label{ display:block; font-size:14px; color:var(--text-secondary); margin-bottom:8px; font-weight:500; }
|
||||
input,select,button{
|
||||
padding:12px 16px;
|
||||
font-size:14px;
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
input:focus, select:focus{
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(0,168,255,0.1);
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.primary{
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
box-shadow: 0 4px 12px rgba(0,168,255,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.primary:hover{
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0,168,255,0.4);
|
||||
}
|
||||
.secondary{
|
||||
background: linear-gradient(135deg, var(--accent-green) 0%, #00e6b8 100%);
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
box-shadow: 0 4px 12px rgba(0,216,167,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.secondary:hover{
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0,216,167,0.4);
|
||||
}
|
||||
.danger{
|
||||
background: linear-gradient(135deg, var(--danger) 0%, #ff8e8e 100%);
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
box-shadow: 0 4px 12px rgba(255,107,107,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.danger:hover{
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(255,107,107,0.4);
|
||||
}
|
||||
|
||||
.link{
|
||||
color:var(--primary);
|
||||
text-decoration:none;
|
||||
margin-left:8px;
|
||||
font-weight:500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.link:hover{
|
||||
color:var(--primary-dark);
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
.muted{ color:var(--text-muted); }
|
||||
|
||||
/* 卡片样式 */
|
||||
.card {
|
||||
background: white;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.05);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 3px solid var(--primary);
|
||||
}
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* Stats Cards */
|
||||
.stats-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.stat-card {
|
||||
color: white;
|
||||
padding: 20px;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
margin: 8px 0;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.stat-icon {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Table */
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.data-table th {
|
||||
background: linear-gradient(135deg, var(--primary-light) 0%, rgba(0,168,255,0.1) 100%);
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 2px solid var(--primary);
|
||||
text-align: left;
|
||||
}
|
||||
.data-table td {
|
||||
padding: 14px 20px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.data-table tr:nth-child(odd) {
|
||||
background: #fcfdff;
|
||||
}
|
||||
.data-table tr:hover {
|
||||
background: var(--hover);
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 100;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.modal.active {
|
||||
display: flex;
|
||||
}
|
||||
.modal-content {
|
||||
background: white;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.tool-tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin: 16px 0 24px 0;
|
||||
}
|
||||
.tab-btn {
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.tab-btn.active {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(0,168,255,0.3);
|
||||
}
|
||||
.tab-content {
|
||||
display: none;
|
||||
}
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.grid-3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.grid-4 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
/* Plan Badge */
|
||||
.plan-badge {
|
||||
background: #e3f2fd;
|
||||
color: #1976d2;
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.calendar-wrapper { background: var(--surface); padding: 16px; border-radius: 16px; box-shadow: 0 4px 12px rgba(0,0,0,0.06); }
|
||||
.calendar { width: 100%; border-collapse: separate; border-spacing: 0; }
|
||||
.calendar th { padding: 8px; color: var(--text-secondary); }
|
||||
.calendar td { vertical-align: top; border: 1px solid var(--border); padding: 8px; min-height: 80px; }
|
||||
.calendar td.empty { background: #f5f7fa; }
|
||||
.calendar .date { font-weight: 600; color: var(--text-primary); margin-bottom: 6px; }
|
||||
.calendar .metric { font-size: 12px; color: var(--text-secondary); }
|
||||
.calendar .small { font-size: 12px; color: var(--text-muted); }
|
||||
.calendar td:hover { background: var(--hover); }
|
||||
|
||||
.screen-card { background: #0b2e4f; color: #cfe8ff; padding: 16px; border-radius: 16px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
|
||||
.screen-card .label { font-size: 14px; opacity: 0.9; margin-bottom: 8px; }
|
||||
.screen-card .progress-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
.progress-item { margin-bottom: 8px; }
|
||||
.progress-title { font-size: 14px; color: #cfe8ff; margin-bottom: 6px; }
|
||||
.progress { width: 100%; height: 10px; background: rgba(207,232,255,0.2); border-radius: 999px; overflow: hidden; }
|
||||
.progress .fill { height: 100%; background: #4fc3f7; }
|
||||
|
||||
.filter-bar { background: #f8fafc; padding: 16px; border-radius: 12px; margin-bottom: 20px; }
|
||||
.range-btn { padding: 8px 12px; border: none; background: #fff; border-radius: 12px; cursor: pointer; font-weight: 600; color: var(--text-secondary); border: 2px solid var(--border); }
|
||||
.range-btn:hover { border-color: var(--primary); }
|
||||
|
||||
.card-complete {
|
||||
background: linear-gradient(135deg, rgba(0,216,167,0.1) 0%, rgba(0,216,167,0.05) 100%);
|
||||
border-left: 4px solid var(--accent-green);
|
||||
position: relative;
|
||||
}
|
||||
.card-incomplete {
|
||||
background: linear-gradient(135deg, rgba(255,107,107,0.1) 0%, rgba(255,107,107,0.05) 100%);
|
||||
border-left: 4px solid var(--danger);
|
||||
position: relative;
|
||||
}
|
||||
.num-remain { color: var(--danger); font-weight: 700; }
|
||||
.num-goal { color: var(--primary); font-weight: 700; }
|
||||
.num-done { color: var(--accent-green); font-weight: 700; }
|
||||
.flag {
|
||||
position: absolute; right: 16px; top: 16px;
|
||||
width: 56px; height: 56px;
|
||||
background-size: contain; background-repeat: no-repeat; background-position: center;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
.container { padding: 0 12px; }
|
||||
.tool-tabs { flex-wrap: wrap; row-gap: 8px; }
|
||||
.tab-btn { padding: 8px 12px; }
|
||||
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
|
||||
.card-header { flex-direction: column; align-items: flex-start; gap: 8px; }
|
||||
.stat-value { font-size: 28px; }
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.card { padding: 16px; }
|
||||
.data-table th, .data-table td { padding: 10px; }
|
||||
.modal-content { width: 96%; }
|
||||
}
|
||||
|
||||
/* 完成奖励红旗(使用本地图片) */
|
||||
.card-complete::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
background-image: url('images/qizi.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
.card-complete .flag { display: none; }
|
||||
@@ -0,0 +1,444 @@
|
||||
/* 活力运动风格:清爽蓝/绿/橙系配色方案 */
|
||||
:root{
|
||||
/* 主色调:清爽蓝色系 */
|
||||
--primary: #00a8ff; /* 活力蓝 */
|
||||
--primary-light: #4cdfff; /* 浅蓝 */
|
||||
--primary-dark: #0077cc; /* 深蓝 */
|
||||
|
||||
/* 辅助色:绿色和橙色系 */
|
||||
--accent-green: #00d8a7; /* 活力绿 */
|
||||
--accent-orange: #ff9f43; /* 活力橙 */
|
||||
--accent-yellow: #feca57; /* 阳光黄 */
|
||||
|
||||
/* 中性色 */
|
||||
--secondary: #4a4a4a; /* 深灰 */
|
||||
--danger: #ff6b6b; /* 活力红 */
|
||||
--success: #00d8a7; /* 成功绿 */
|
||||
--warning: #ff9f43; /* 警告橙 */
|
||||
|
||||
/* 背景与表面 */
|
||||
--bg: #f8fafc; /* 浅灰背景 */
|
||||
--surface: #ffffff; /* 白色表面 */
|
||||
--border: #e1e8ed; /* 浅灰边框 */
|
||||
--hover: #f0f7ff; /* 悬停蓝色 */
|
||||
|
||||
/* 文字色 */
|
||||
--text-primary: #2c3e50; /* 深蓝灰 */
|
||||
--text-secondary: #7f8c8d; /* 中灰 */
|
||||
--text-muted: #95a5a6; /* 浅灰 */
|
||||
}
|
||||
|
||||
*{ box-sizing:border-box; }
|
||||
body{ margin:0; font-family:'PingFang SC', 'Helvetica Neue', Arial, sans-serif; background:var(--bg); color:var(--text-primary); line-height:1.6; }
|
||||
|
||||
/* 顶部导航(运动风格) */
|
||||
.nav{
|
||||
display:flex; justify-content:space-between; align-items:center;
|
||||
padding:16px 20px;
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--accent-green) 100%);
|
||||
color:white;
|
||||
box-shadow: 0 4px 20px rgba(0,168,255,0.15);
|
||||
position:sticky; top:0; z-index:10;
|
||||
}
|
||||
.nav-left{
|
||||
font-weight:700; font-size:20px;
|
||||
text-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.nav a{ text-decoration:none; }
|
||||
.nav-right{
|
||||
display:flex; flex-wrap:nowrap;
|
||||
overflow-x:auto; -webkit-overflow-scrolling:touch;
|
||||
background: rgba(255,255,255,0.15);
|
||||
border-radius: 25px;
|
||||
padding: 4px;
|
||||
}
|
||||
.nav-right::-webkit-scrollbar{ display:none; }
|
||||
.nav-right a{
|
||||
position:relative; margin:0 2px;
|
||||
padding:8px 16px;
|
||||
color:rgba(255,255,255,0.9);
|
||||
text-decoration:none;
|
||||
border-radius:20px;
|
||||
transition:all 0.3s ease;
|
||||
font-weight:500;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.nav-right a:hover{
|
||||
color:white;
|
||||
background:rgba(255,255,255,0.2);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.nav-right a.active{
|
||||
color:var(--primary);
|
||||
background:white;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.container{ max-width:1080px; margin:24px auto; padding:0 20px; }
|
||||
|
||||
/* 通用控件 - 运动风格 */
|
||||
label{ display:block; font-size:14px; color:var(--text-secondary); margin-bottom:8px; font-weight:500; }
|
||||
input,select,button{
|
||||
padding:12px 16px;
|
||||
font-size:14px;
|
||||
border: 2px solid var(--border);
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
input:focus, select:focus{
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(0,168,255,0.1);
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.primary{
|
||||
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
box-shadow: 0 4px 12px rgba(0,168,255,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.primary:hover{
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0,168,255,0.4);
|
||||
}
|
||||
.secondary{
|
||||
background: linear-gradient(135deg, var(--accent-green) 0%, #00e6b8 100%);
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
box-shadow: 0 4px 12px rgba(0,216,167,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.secondary:hover{
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0,216,167,0.4);
|
||||
}
|
||||
.danger{
|
||||
background: linear-gradient(135deg, var(--danger) 0%, #ff8e8e 100%);
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
box-shadow: 0 4px 12px rgba(255,107,107,0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.danger:hover{
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(255,107,107,0.4);
|
||||
}
|
||||
|
||||
.link{
|
||||
color:var(--primary);
|
||||
text-decoration:none;
|
||||
margin-left:8px;
|
||||
font-weight:500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.link:hover{
|
||||
color:var(--primary-dark);
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
.muted{ color:var(--text-muted); }
|
||||
|
||||
/* 卡片样式 */
|
||||
.card {
|
||||
background: white;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.05);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 3px solid var(--primary);
|
||||
}
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* Stats Cards */
|
||||
.stats-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.stat-card {
|
||||
color: white;
|
||||
padding: 20px;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
margin: 8px 0;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.stat-icon {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Table */
|
||||
.table-responsive { overflow-x: auto; }
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.data-table th {
|
||||
background: linear-gradient(135deg, var(--primary-light) 0%, rgba(0,168,255,0.1) 100%);
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 2px solid var(--primary);
|
||||
text-align: left;
|
||||
}
|
||||
.data-table td {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.data-table tr:nth-child(odd) {
|
||||
background: #fcfdff;
|
||||
}
|
||||
.data-table tr:hover {
|
||||
background: var(--hover);
|
||||
}
|
||||
|
||||
.weekly-warning {
|
||||
margin-top: 16px;
|
||||
padding: 12px 16px;
|
||||
border: 2px solid var(--danger);
|
||||
border-radius: 12px;
|
||||
background: rgba(255, 107, 107, 0.08);
|
||||
color: var(--danger);
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 100;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.modal.active {
|
||||
display: flex;
|
||||
}
|
||||
.modal-content {
|
||||
background: white;
|
||||
padding: 24px;
|
||||
border-radius: 16px;
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.tool-tabs {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin: 16px 0 24px 0;
|
||||
}
|
||||
.tab-btn {
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.tab-btn.active {
|
||||
background: var(--primary);
|
||||
color: white;
|
||||
box-shadow: 0 4px 12px rgba(0,168,255,0.3);
|
||||
}
|
||||
.tab-content {
|
||||
display: none;
|
||||
}
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.grid-3 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.grid-4 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.health-metrics-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
.stats-filter-grid { grid-template-columns: 1fr; }
|
||||
.filter-actions-right { text-align: left; width: 100%; }
|
||||
.mobile-input { width: 100%; }
|
||||
.health-metrics-grid {
|
||||
gap: 8px; /* 减小间距 */
|
||||
}
|
||||
.health-metrics-grid label, .health-metrics-grid input {
|
||||
font-size: 12px; /* 减小字体 */
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.btn-sm { padding: 6px 10px; font-size: 12px; }
|
||||
.health-metrics-grid {
|
||||
gap: 4px; /* 进一步减小间距 */
|
||||
}
|
||||
.health-metrics-grid label, .health-metrics-grid input {
|
||||
font-size: 10px; /* 进一步减小字体 */
|
||||
}
|
||||
}
|
||||
|
||||
.card-complete {
|
||||
background: linear-gradient(135deg, rgba(0,216,167,0.1) 0%, rgba(0,216,167,0.05) 100%);
|
||||
border-left: 4px solid var(--accent-green);
|
||||
position: relative;
|
||||
}
|
||||
.card-incomplete {
|
||||
background: linear-gradient(135deg, rgba(255,107,107,0.1) 0%, rgba(255,107,107,0.05) 100%);
|
||||
border-left: 4px solid var(--danger);
|
||||
position: relative;
|
||||
}
|
||||
.num-remain { color: var(--danger); font-weight: 700; }
|
||||
.num-goal { color: var(--primary); font-weight: 700; }
|
||||
.num-done { color: var(--accent-green); font-weight: 700; }
|
||||
.flag {
|
||||
position: absolute; right: 16px; top: 16px;
|
||||
width: 56px; height: 56px;
|
||||
background-size: contain; background-repeat: no-repeat; background-position: center;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
.container { padding: 0 12px; }
|
||||
.tool-tabs { flex-wrap: wrap; row-gap: 8px; }
|
||||
.tab-btn { padding: 8px 12px; }
|
||||
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
|
||||
.card-header { flex-direction: column; align-items: flex-start; gap: 8px; }
|
||||
.stat-value { font-size: 28px; }
|
||||
.screen-card canvas { height: 180px; }
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.card { padding: 16px; }
|
||||
.data-table th, .data-table td { padding: 10px; }
|
||||
.modal-content { width: 96%; }
|
||||
}
|
||||
|
||||
/* 设置页表格 - 列宽与操作列固定 */
|
||||
#section-settings .data-table { table-layout: fixed; }
|
||||
#section-settings .data-table th:nth-child(1),
|
||||
#section-settings .data-table td:nth-child(1) { width: 40%; }
|
||||
#section-settings .data-table th:nth-child(2),
|
||||
#section-settings .data-table td:nth-child(2) { width: 16%; }
|
||||
#section-settings .data-table th:nth-child(3),
|
||||
#section-settings .data-table td:nth-child(3) { width: 16%; }
|
||||
#section-settings .data-table th:nth-child(4),
|
||||
#section-settings .data-table td:nth-child(4) { width: 12%; }
|
||||
#section-settings .data-table th:nth-child(5),
|
||||
#section-settings .data-table td:nth-child(5) { width: 16%; }
|
||||
#section-settings .data-table th:last-child,
|
||||
#section-settings .data-table td:last-child { position: sticky; right: 0; z-index: 3; background: #fff; }
|
||||
#section-settings input[type="text"],
|
||||
#section-settings input[type="number"],
|
||||
#section-settings select { width: 100%; box-sizing: border-box; }
|
||||
|
||||
|
||||
/* 完成奖励红旗(使用本地图片) */
|
||||
.card-complete::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
top: 16px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
background-image: url('images/qizi.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
/* Waiting Box Styles */
|
||||
.waiting-steps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.waiting-step {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.waiting-step.pending { opacity: 0.6; }
|
||||
.waiting-step.active { color: var(--primary); font-weight: 600; }
|
||||
.waiting-step.done { color: var(--success); }
|
||||
.waiting-step.error { color: var(--danger); }
|
||||
.step-icon {
|
||||
width: 20px; height: 20px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
.spinner {
|
||||
width: 16px; height: 16px;
|
||||
border: 2px solid var(--primary);
|
||||
border-top-color: transparent;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
@keyframes spin { 100% { transform: rotate(360deg); } }
|
||||
Reference in New Issue
Block a user