feat: 体重管理原型更新(员工端运动建议v2、管理端员工数据记录页调整及PRD、截图同步)

This commit is contained in:
liuyunqin
2026-08-25 14:32:22 +08:00
parent 9f8a80eae9
commit e76ca89ae6
25 changed files with 89 additions and 50 deletions
+5 -2
View File
@@ -567,13 +567,16 @@ stateDiagram-v2
**功能说明:** 为员工提供个性化运动指导方案,展示本周运动建议、周目标概览与每日运动安排。
**主要UI元素:**
- 周历(含月历弹窗):日期用圆环标记有无运动计划
- 周历(含月历弹窗):日期用圆环标记有无运动计划,圆环颜色区分日期类型——锻炼日绿圈、休息日橙圈,日历下方附图例说明
- 本周运动建议(可折叠):运动频率/强度建议 + 高血压/高尿酸提示条
- 本周目标概览卡片:运动天数 / 周消耗(kcal)/ 周时长(分钟)/ 休息日
- 每日运动安排卡片:日期徽章 + 当日目标消耗/时长 + 类型标签 + 运动项列表(图标 + 名称 + 描述 + 时长/强度 + 消耗)
- 每日运动安排卡片:日期徽章(休息日为橙色徽章)+ 当日目标消耗/时长 + 类型标签 + 运动项列表(图标 + 名称 + 描述 + 时长/强度 + 消耗)
**交互说明:**
- 点击周历日期切换查看当日运动安排;点击周历标题打开月历弹窗,可在弹窗内切换月份并点选日期
- 月历弹窗内同样以圆环标记有计划的日期(绿圈=锻炼日、橙圈=休息日),弹窗底部附图例说明
![月历弹窗](screenshots/exercise-advice-month.jpg)
- 点击运动建议标题折叠/展开
- 点击返回按钮返回上一页
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 173 KiB

@@ -40,11 +40,20 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.month-picker__nav:hover { background: #f0f0f0; }
.month-picker__weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: 11px; color: #bbb; margin-bottom: 6px; }
.month-picker__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.month-picker__day { padding: 6px 0; font-size: 13px; color: #333; border-radius: 8px; cursor: pointer; font-weight: 500; }
.month-picker__day { position: relative; padding: 6px 0; font-size: 13px; color: #333; border-radius: 8px; cursor: pointer; font-weight: 500; }
.month-picker__day:hover { background: #f5f5f5; }
.month-picker__day--other { color: #ddd; }
.month-picker__day--today { background: #f0fff0; color: #52c41a; font-weight: 700; }
.month-picker__day--selected { background: #52c41a; color: #fff; font-weight: 700; }
/* 圈圈区分锻炼日/休息日 */
.month-picker__day--plan .month-picker__ring { position: absolute; top: 50%; left: 50%; width: 24px; height: 24px; margin: -12px 0 0 -12px; border-radius: 50%; border: 2px solid #52c41a; opacity: 0.55; pointer-events: none; }
.month-picker__day--plan.month-picker__day--selected .month-picker__ring { border-color: #fff; opacity: 0.9; }
.month-picker__day--rest .month-picker__ring { border-color: #fa8c16; }
/* 月历弹窗图例 */
.month-picker__legend { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed #f0f0f0; }
.month-picker__legend-item { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: #999; }
.month-picker__legend-dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid #52c41a; }
.month-picker__legend-dot--rest { border-color: #fa8c16; }
.cal-week { display: flex; gap: 4px; }
.cal-day { flex: 1; text-align: center; padding: 6px 0; border-radius: 10px; cursor: pointer; background: #f7f8fa; transition: background .2s; }
@@ -57,8 +66,15 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.cal-day__num { font-size: 14px; font-weight: 700; color: #333; position: relative; z-index: 2; }
.cal-day__ring { position: absolute; inset: 0; border-radius: 50%; border: 2.5px solid #52c41a; z-index: 1; opacity: 0.35; }
.cal-day.active .cal-day__ring { opacity: 1; }
.cal-day--rest .cal-day__ring { border-color: #fa8c16; }
.cal-day.no-plan { opacity: 0.4; }
/* 日历图例 */
.cal-legend { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 6px; padding-top: 6px; border-top: 1px dashed #f0f0f0; }
.cal-legend__item { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: #999; }
.cal-legend__dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid #52c41a; }
.cal-legend__dot--rest { border-color: #fa8c16; }
/* ===== 运动建议摘要卡片 ===== */
.advice-summary { background: linear-gradient(160deg, #f0fff0, #f6ffed); border-radius: 16px; margin: 10px 12px 0; padding: 14px 16px; border: 1px solid #b7ebc4; }
.advice-summary__header { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
@@ -194,9 +210,20 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<span></span><span></span><span></span><span></span><span></span><span></span><span></span>
</div>
<div class="month-picker__grid" id="monthGrid"></div>
<!-- 图例:圈圈颜色区分锻炼日/休息日 -->
<div class="month-picker__legend">
<span class="month-picker__legend-item"><span class="month-picker__legend-dot"></span>锻炼日</span>
<span class="month-picker__legend-item"><span class="month-picker__legend-dot month-picker__legend-dot--rest"></span>休息日</span>
</div>
</div>
<div class="cal-week" id="calWeek"></div>
<!-- 图例:圈圈颜色区分锻炼日/休息日 -->
<div class="cal-legend">
<span class="cal-legend__item"><span class="cal-legend__dot"></span>锻炼日</span>
<span class="cal-legend__item"><span class="cal-legend__dot cal-legend__dot--rest"></span>休息日</span>
</div>
</div>
<!-- ===== 2. 运动建议摘要(可折叠) ===== -->
@@ -368,10 +395,12 @@ function renderWeek() {
var wd = weekDayChars[d.getDay()];
var dayNum = d.getDate();
var isToday = isSameDay(d, today);
var hasPlan = !!weekPlans[dateStr];
var plan = weekPlans[dateStr];
var hasPlan = !!plan;
var isRest = hasPlan && plan.rest;
var dayEl = document.createElement('div');
dayEl.className = 'cal-day' + (isToday ? ' today' : '') + (!hasPlan ? ' no-plan' : '');
dayEl.className = 'cal-day' + (isToday ? ' today' : '') + (isRest ? ' cal-day--rest' : '') + (!hasPlan ? ' no-plan' : '');
dayEl.setAttribute('data-date', dateStr);
dayEl.onclick = function() { selectDay(this); };
@@ -487,12 +516,14 @@ function renderMonthGrid() {
for (var d = 1; d <= daysInMonth; d++) {
var dateStr = pickerYear + '-' + ('0' + (pickerMonth + 1)).slice(-2) + '-' + ('0' + d).slice(-2);
var plan = weekPlans[dateStr];
var el = document.createElement('div');
var cls = 'month-picker__day';
if (dateStr === todayStr) cls += ' month-picker__day--today';
if (dateStr === selectedDate) cls += ' month-picker__day--selected';
if (plan) cls += plan.rest ? ' month-picker__day--rest' : ' month-picker__day--plan';
el.className = cls;
el.textContent = d;
el.innerHTML = (plan ? '<span class="month-picker__ring"></span>' : '') + d;
el.onclick = (function(ds) { return function(e) { e.stopPropagation(); pickDay(ds); }; })(dateStr);
grid.appendChild(el);
}