From ea8239debf965c7dcb5541dae20aed48faa1e4ea Mon Sep 17 00:00:00 2001 From: fengpu <18691763612@163.com> Date: Thu, 23 Jul 2026 16:49:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AE=A1=E7=90=86=E7=AB=AF=E5=9C=BA?= =?UTF-8?q?=E6=89=80/=E5=88=86=E7=B1=BB=E7=AE=A1=E7=90=86=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E5=8F=8A=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=AB=AF=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后台营养管理:场所新增/编辑页重构(营业时段/图片/资质)、食材及餐品分类管理弹窗、从已有食材复制 - 营养管理小程序:净菜包订单按状态差异化展示、时间选择器交互重构、新增收货地址页、移除营养目标分区 - CHANGELOG 更新至 2026-07-23 Co-Authored-By: Claude Opus 4.7 --- .claude/memory/MEMORY.md | 4 +- .claude/memory/lint_report.md | 12 +- .claude/memory/project_progress.md | 1 + CLAUDE.md | 2 - employee-app/weight-management/doc/PRD.md | 9 +- index.html | 1 + .../nutrition/eat-order-confirm.html | 151 ++++-- .../mini-program/nutrition/eat-order.html | 41 +- .../mini-program/nutrition/me-address.html | 426 ++++++++++++++++ .../mini-program/nutrition/me-health.html | 56 +-- .../mini-program/nutrition/me-home.html | 1 + .../nutrition/me-order-detail.html | 131 ++++- .../mini-program/nutrition/me-orders.html | 4 +- web-admin/nutrition/din-canteen-add.html | 466 ++++++++++++++++-- web-admin/nutrition/din-canteen.html | 145 +++++- web-admin/nutrition/din-dish-all.html | 184 +++++++ web-admin/nutrition/din-ingredient-add.html | 220 ++++++++- web-admin/nutrition/din-ingredient.html | 227 ++++++++- web-admin/nutrition/doc/CHANGELOG.md | 20 + 19 files changed, 1911 insertions(+), 190 deletions(-) create mode 100644 other-module/mini-program/nutrition/me-address.html diff --git a/.claude/memory/MEMORY.md b/.claude/memory/MEMORY.md index d32a60f..0dbe568 100644 --- a/.claude/memory/MEMORY.md +++ b/.claude/memory/MEMORY.md @@ -1,10 +1,10 @@ -_Last synced: 2026-07-20 | Base commit: `5c518cb`_ +_Last synced: 2026-07-21 | Base commit: `f671764`_ # 记忆索引 | 文件 | 描述 | 类型 | 最后更新 | |------|------|------|----------| | project_overview.md | 项目技术栈、架构与模块结构 | project | 2026-05-14 | -| project_progress.md | 各模块原型开发进度 | project | 2026-07-20 | +| project_progress.md | 各模块原型开发进度 | project | 2026-07-21 | | decisions.md | 关键设计决策与架构约定 | project | 2026-06-15 | | feedback.md | 协作规范与用户纠正记录 | feedback | 2026-06-15 | | user_profile.md | 用户角色与偏好 | user | 2026-04-21 | diff --git a/.claude/memory/lint_report.md b/.claude/memory/lint_report.md index 71bb60d..9db7594 100644 --- a/.claude/memory/lint_report.md +++ b/.claude/memory/lint_report.md @@ -2,12 +2,12 @@ name: 记忆健康检查报告 description: memory-lint 最新一次执行的检查结果与待处理项 type: lint -last_updated: 2026-07-20 +last_updated: 2026-07-21 --- # 记忆健康检查报告 -> _执行时间: 2026-07-20 | Base commit: `5c518cb` | Last synced: 2026-07-20_ +> _执行时间: 2026-07-21 | Base commit: `f671764` | Last synced: 2026-07-21_ ## 健康概览 @@ -35,17 +35,17 @@ last_updated: 2026-07-20 ### [ERROR] 过期记忆 -- **文件**:`user_profile.md`(last_updated: 2026-04-21,已过期 90 天) +- **文件**:`user_profile.md`(last_updated: 2026-04-21,已过期 91 天) - **建议**:若用户角色或协作偏好发生变化,执行 `/memory-update` 更新;否则可忽略 ### [WARN] 过期记忆 -- **文件**:`project_overview.md`(last_updated: 2026-05-14,已过期 67 天) +- **文件**:`project_overview.md`(last_updated: 2026-05-14,已过期 68 天) - 自上次更新后项目新增净菜贴标秤、净菜组配秤重构、营养边缘服务、西安应急大屏 v2/v3、蓝牙体重秤小程序等模块 - **建议**:若需同步技术栈/架构变化,执行 `/memory-update` 或手动补充模块结构说明 -- **文件**:`decisions.md`(last_updated: 2026-06-15,已过期 35 天) +- **文件**:`decisions.md`(last_updated: 2026-06-15,已过期 36 天) - **建议**:若期间产生新的关键决策,执行 `/memory-update` 补充;否则可忽略 -- **文件**:`feedback.md`(last_updated: 2026-06-15,已过期 35 天) +- **文件**:`feedback.md`(last_updated: 2026-06-15,已过期 36 天) - **建议**:若期间产生新的协作规范纠正,执行 `/memory-update` 补充;否则可忽略 --- diff --git a/.claude/memory/project_progress.md b/.claude/memory/project_progress.md index b0808c4..7a6c20c 100644 --- a/.claude/memory/project_progress.md +++ b/.claude/memory/project_progress.md @@ -89,6 +89,7 @@ Web 管理端和员工端 APP 的其余模块(系统管理、运动管理、 - 覆盖模块:18 个(含三端+其他终端) ## 近期里程碑 +- 2026-07-21:导航页 popover 事件冒泡回归再次修复(同一根因第二次出现)——0603113 提交将 popover 重构为延迟渲染模式(首次点击"X 页"才动态构建 DOM),但 `togglePop` 函数内 `insertAdjacentHTML` 模板漏加 `onclick="event.stopPropagation()"`,导致同样的双 tab 打开回归。修复方式:在延迟构建模板中补上 stopPropagation(commit f671764)。系统性教训:嵌套 onclick 结构中子容器的 stopPropagation 在代码重构时极易遗漏,后续涉及 popover/弹层 DOM 创建位置变更时需检查事件冒泡拦截。 - 2026-07-20:导航页 popover 事件冒泡回归修复——8a96ead 提交重构 popover 关闭逻辑时误删 `
` 上的 `onclick="event.stopPropagation()"`,导致 popover 内 `` 点击事件冒泡到父级 `module-card` 触发 `window.open` 打开模块入口页,与 `` 默认跳转叠加造成点击"页面总览"等列表项时同时打开两个 tab。修复方式:恢复 popover 容器上的 stopPropagation,与新版本 document click 监听器(靠 `closest` 判断)兼容(commit 5c518cb)。 - 2026-07:本月重要变更摘要——新增蓝牙体重秤小程序模块 `other-module/bluetooth-scale-miniprogram/`(11 页:登录/搜索设备/wifi连接/添加成员/设备成员/主页/数据详情/资料完善/帮助中心/帮助详情/资料);西安应急大屏 v3 系列重构与扩展(主屏 v3 重构+路径规划纵向逐步导航+体检雷达/穿戴统计数值带单位+体重管理今日维度、cv 副屏重构为穿戴告警监测+新增告警趋势/心脑血管预警/告警时段分布、新增 help-monitor 应急求助副屏、新增多个业务记录弹窗含筛选与分页、站点入口指向 v3);营养管理后台菜单用户操作权限划分;营养管理小程序原型页面调整(小程序购买净菜包+健康档案+加餐数据展示);体重管理 web-admin 多页面更新(archive-unit-report-detail、history-personnel-list/detail、plan-edit、action-record 等);健康监测模块更新。 - 2026-06-26:餐厅终端设备净菜包装秤与组配秤迭代——净菜包装秤全模块完成“贴标”到“包装”的术语统一,包装作业页清单按 `packSize` 展开为单份、移除称重弹窗并改为直接读秤,新增搜索框与 `label-preview.html` 标签预览页;净菜组配秤任务/历史页按单份拆分展示,食材名称去除丝/段/片/块/液等后缀,组配作业页移除确认弹窗并优化底部按钮布局;同步删除根目录个人化全平台进度生成脚本 `scripts/generate-overview.js`。 diff --git a/CLAUDE.md b/CLAUDE.md index d3d0fac..ba12a61 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,3 @@ - - # 项目约束 本项目所有工作必须严格遵守 `项目背景.md` 中定义的全部规范,包括: diff --git a/employee-app/weight-management/doc/PRD.md b/employee-app/weight-management/doc/PRD.md index 95d0863..a54731d 100644 --- a/employee-app/weight-management/doc/PRD.md +++ b/employee-app/weight-management/doc/PRD.md @@ -439,8 +439,8 @@ stateDiagram-v2 **主要UI元素:** - 导航栏标题:当前日期 -- 今日摘要栏:显示已记录餐数和总摄入热量,右侧"历史记录"链接跳转到摄入记录页面 -- 四餐卡片(早餐/午餐/晚餐/加餐):各显示已摄入热量、推荐热量参考、来源徽章(智记/自记/未记录) +- 今日摘要栏:显示当日已记录餐数和总摄入热量,右侧"历史记录"链接跳转到摄入记录页面 +- 四餐卡片(早餐/午餐/晚餐/加餐):各显示已摄入热量、推荐热量参考、来源徽章(智记/自记/智记+自记/未记录) - 类型显示当日总记录卡片(智记/自记) - 自记区域:搜索框、左侧分类列表、右侧菜品列表(含+/-按钮) - 底部固定栏:购物袋图标(显示已选菜品数量)、总热量、提交按钮 @@ -470,8 +470,8 @@ stateDiagram-v2 **主要UI元素:** - 导航栏标题:当前周日期范围(如"08-10 ~ 08-16") - 今日摘要栏:显示当天日期、星期、今日消耗热量,"历史记录"链接跳转到消耗记录页面 -- 一周日期卡片(2行,4+3布局):周一至周日,已记录天显示步数/消耗热量+来源徽章(微信/穿戴/器械/自记)、推荐步数,当天高亮 -- 来源类型卡片:穿戴设备(步数)、器械运动(已记录时长)、微信运动(步数+同步按钮)、自记运动(已记录时长) +- 一周日期卡片(2行,4+3布局):周一至周日,已记录天显示步数/消耗热量(有步数只显示步数,没有步数则显示消耗热量)+来源徽章(微信/穿戴/器械/自记)、推荐步数,当天高亮 +- 来源类型卡片:穿戴设备(步数)、器械运动(已记录时长)、微信运动(步数+同步按钮)、自记运动(步数/已记录运动时长【有步数只显示步数,没有步数则显示运动时长】) - 自记区域:搜索框、运动分类、运动项目列表(含+/-按钮) - 底部固定栏:购物袋图标(显示已选运动数)、总消耗热量、提交按钮 @@ -488,6 +488,7 @@ stateDiagram-v2 - 穿戴设备未记录时,点击提示“您未配备或未连接穿戴设备”弹窗 - 日期卡片中的已记录数据,如果穿戴、自记、微信都有步数,取最大值。如果没有步数,则显示消耗千卡 - 微信运动需手动触发同步 +- 注意:因穿戴设备数据以及微信运动数据存在补传历史数据的情况,体重管理业务中只再做数据归档时允许修正T-2的数据(在归档昨天的数据前要修正前天的数据); --- diff --git a/index.html b/index.html index 0b734e3..1892b44 100644 --- a/index.html +++ b/index.html @@ -851,6 +851,7 @@ const SITE_MAP = [ {label:'我的创作', file:'make-my-recipes.html'}, {label:'微信授权登录', file:'me-login.html'}, {label:'个人中心', file:'me-home.html'}, + {label:'收货地址', file:'me-address.html'}, {label:'健康档案', file:'me-health.html'}, {label:'我的订单', file:'me-orders.html'}, {label:'订单详情', file:'me-order-detail.html'}, diff --git a/other-module/mini-program/nutrition/eat-order-confirm.html b/other-module/mini-program/nutrition/eat-order-confirm.html index a1e5eed..87a2671 100644 --- a/other-module/mini-program/nutrition/eat-order-confirm.html +++ b/other-module/mini-program/nutrition/eat-order-confirm.html @@ -92,16 +92,42 @@ .pickup-method .pm-name { font-size: 13px; font-weight: 600; margin-top: 4px; color: #333; } .pickup-method .pm-desc { font-size: 10px; color: #999; margin-top: 2px; } .pickup-method.active .pm-name { color: #1677ff; } - /* 日期/时段 chip */ - .chip-label { font-size: 11px; color: #999; margin: 8px 0 6px; } - .date-chips, .time-chips { display: flex; gap: 6px; flex-wrap: wrap; } - .date-chip, .time-chip { - padding: 6px 10px; border-radius: 14px; background: #f5f5f5; - font-size: 11px; color: #666; cursor: pointer; line-height: 1.4; + /* 期望配送时间:下拉框风格 */ + .time-picker-trigger { + display: flex; align-items: center; justify-content: space-between; + height: 38px; padding: 0 12px; border-radius: 8px; + border: 1px solid #e8e8e8; background: #fff; cursor: pointer; } - .date-chip.active, .time-chip.active { - background: #1677ff; color: #fff; font-weight: 600; + .tpt-text { font-size: 13px; color: #333; } + .tpt-arrow { font-size: 10px; color: #999; transition: transform 0.2s; } + .tpt-arrow.open { transform: rotate(180deg); } + .time-picker-panel { + display: none; margin-top: 6px; gap: 8px; } + .time-picker-panel.show { display: flex; } + .tp-date-col { + width: 88px; flex-shrink: 0; display: flex; flex-direction: column; gap: 4px; + } + .tp-date-card { + padding: 7px 6px; border-radius: 6px; border: 1px solid #e8e8e8; + text-align: center; cursor: pointer; background: #fff; transition: all 0.15s; + } + .tp-date-card.active { border-color: #1677ff; background: #e6f4ff; } + .tp-date-card .tp-date-week { font-size: 10px; color: #999; margin-bottom: 2px; } + .tp-date-card.active .tp-date-week { color: #1677ff; font-weight: 600; } + .tp-date-card .tp-date-day { font-size: 12px; color: #333; font-weight: 600; } + .tp-date-card.active .tp-date-day { color: #1677ff; } + .tp-time-col { + flex: 1; max-height: 220px; overflow-y: auto; + display: flex; flex-direction: column; gap: 2px; + border: 1px solid #e8e8e8; border-radius: 6px; padding: 4px 6px; + } + .tp-time-col::-webkit-scrollbar { display: none; } + .tp-time-item { + padding: 6px 10px; border-radius: 6px; font-size: 12px; color: #333; + cursor: pointer; text-align: center; transition: all 0.15s; + } + .tp-time-item.active { background: #1677ff; color: #fff; font-weight: 600; } /* 地址卡片 */ .address-card, .pickup-card { padding: 12px; border-radius: 8px; border: 1px solid #e8e8e8; background: #fafafa; @@ -225,8 +251,6 @@
- +
期望配送时间 *
-
选择日期
-
-
今日(4月28日)
-
明日(4月29日)
-
4月30日
+
+ 4月30日 周五 | 11:00-12:00 +
-
选择时段
-
-
早餐 07:00-08:00
-
午餐 11:00-12:00
-
晚餐 17:00-18:00
+
+
+
+
周五
+
4月30日
+
+
+
周六
+
5月1日
+
+
+
周日
+
5月2日
+
+
+
+
07:00-08:00
+
08:00-09:00
+
09:00-10:00
+
10:00-11:00
+
11:00-12:00
+
12:00-13:00
+
13:00-14:00
+
14:00-15:00
+
15:00-16:00
+
16:00-17:00
+
17:00-18:00
+
18:00-19:00
+
19:00-20:00
+
@@ -371,7 +418,8 @@ var orderAmount = document.getElementById('orderAmount'); var actionBtns = document.getElementById('actionBtns'); - /* 取货方式切换:联动地址组/自提组显示 */ + /* 取货方式切换:联动地址组/自提组 + 时间标签文本 */ + var timeLabel = document.querySelectorAll('.fulfill-card .fg-label')[1]; document.querySelectorAll('.pickup-method').forEach(function(m) { m.addEventListener('click', function() { document.querySelectorAll('.pickup-method').forEach(function(x) { x.classList.remove('active'); }); @@ -379,22 +427,63 @@ var isDelivery = m.dataset.method === 'delivery'; document.getElementById('addressGroup').classList.toggle('hidden', !isDelivery); document.getElementById('pickupGroup').classList.toggle('hidden', isDelivery); + /* 切换标签文本 */ + if (isDelivery) { + timeLabel.innerHTML = '期望配送时间 *'; + } else { + timeLabel.innerHTML = '自提时间 *'; + } }); }); - /* 日期 chip 单选切换 */ - document.querySelectorAll('.date-chip').forEach(function(c) { - c.addEventListener('click', function() { - document.querySelectorAll('.date-chip').forEach(function(x) { x.classList.remove('active'); }); + /* 下拉面板展开/收起 */ + var timePickerTrigger = document.getElementById('timePickerTrigger'); + var timePickerPanel = document.getElementById('timePickerPanel'); + var tptText = document.getElementById('tptText'); + var tptArrow = document.getElementById('tptArrow'); + + timePickerTrigger.addEventListener('click', function(e) { + e.stopPropagation(); + var isOpen = timePickerPanel.classList.toggle('show'); + if (isOpen) { tptArrow.classList.add('open'); } + else { tptArrow.classList.remove('open'); } + }); + + /* 点击面板外部关闭 */ + document.addEventListener('click', function(e) { + if (!timePickerTrigger.contains(e.target) && !timePickerPanel.contains(e.target)) { + timePickerPanel.classList.remove('show'); + tptArrow.classList.remove('open'); + } + }); + + /* 更新触发区显示文本 */ + function updateTriggerText() { + var activeDate = document.querySelector('.tp-date-card.active'); + var activeTime = document.querySelector('.tp-time-item.active'); + var week = activeDate ? activeDate.dataset.week : ''; + var day = activeDate ? activeDate.dataset.day : ''; + var time = activeTime ? activeTime.textContent : ''; + tptText.textContent = day + ' ' + week + ' | ' + time; + } + + /* 日期卡片单选切换 */ + document.querySelectorAll('.tp-date-card').forEach(function(c) { + c.addEventListener('click', function(e) { + e.stopPropagation(); + document.querySelectorAll('.tp-date-card').forEach(function(x) { x.classList.remove('active'); }); c.classList.add('active'); + updateTriggerText(); }); }); - /* 时段 chip 单选切换 */ - document.querySelectorAll('.time-chip').forEach(function(c) { - c.addEventListener('click', function() { - document.querySelectorAll('.time-chip').forEach(function(x) { x.classList.remove('active'); }); + /* 时段列表项单选切换 */ + document.querySelectorAll('.tp-time-item').forEach(function(c) { + c.addEventListener('click', function(e) { + e.stopPropagation(); + document.querySelectorAll('.tp-time-item').forEach(function(x) { x.classList.remove('active'); }); c.classList.add('active'); + updateTriggerText(); }); }); @@ -473,7 +562,7 @@ /* 净菜包订单:改为"确认订单"页,隐藏取餐码,展示履约表单 */ successIcon.textContent = '📝'; successTitle.textContent = '确认订单信息'; - successDesc.textContent = '请补充履约信息后提交订单'; + successDesc.textContent = '请先选择配送方式后再提交订单'; pickupBlock.classList.add('hidden'); fulfillBlock.classList.remove('hidden'); orderItems.innerHTML = diff --git a/other-module/mini-program/nutrition/eat-order.html b/other-module/mini-program/nutrition/eat-order.html index 561415f..f4a52d7 100644 --- a/other-module/mini-program/nutrition/eat-order.html +++ b/other-module/mini-program/nutrition/eat-order.html @@ -68,9 +68,15 @@ .menu-item .food-icon { width: 56px; height: 56px; border-radius: 10px; background: #f5f5f5; display: flex; align-items: center; justify-content: center; font-size: 28px; flex-shrink: 0; + cursor: pointer; } .menu-item .food-info { flex: 1; min-width: 0; } - .menu-item .food-name { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; } + .menu-item .food-name { + font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; + cursor: pointer; + } + .menu-item .food-name:hover { color: #1677ff; } + .menu-item .food-desc { cursor: pointer; } .food-tag { font-size: 10px; font-weight: 600; padding: 1px 5px; border-radius: 3px; white-space: nowrap; line-height: 16px; @@ -236,7 +242,7 @@