diff --git a/_templates/md-viewer.html b/_templates/md-viewer.html index 3d6835d..468da51 100644 --- a/_templates/md-viewer.html +++ b/_templates/md-viewer.html @@ -75,14 +75,6 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica 放大预览 diff --git a/other-module/bluetooth-scale-miniprogram/device-members.html b/other-module/bluetooth-scale-miniprogram/device-members.html index cb1274c..56aecc1 100644 --- a/other-module/bluetooth-scale-miniprogram/device-members.html +++ b/other-module/bluetooth-scale-miniprogram/device-members.html @@ -111,6 +111,7 @@ .member-sync { font-size: 11px; font-weight: 600; margin-left: auto; flex-shrink: 0; } .member-sync--done { color: #389e0d; } .member-sync--pending { color: #ff4d4f; } + .member-sync--deleted { color: #ff4d4f; } .member-detail { font-size: 12px; color: var(--text-placeholder); margin-top: 4px; } .member-actions { display: flex; gap: 12px; margin-top: 8px; } .action-btn { @@ -121,7 +122,10 @@ .action-btn--edit { background: var(--primary-light); color: var(--primary); } .action-btn--delete { background: #fff2f0; color: #ff4d4f; } - /* 同步提示 */ + /* 已删除状态 */ + .member-card--deleted { opacity: 0.45; pointer-events: none; } + + /* 删除确认弹窗 */ .sync-hint { margin: 0 0 12px; padding: 10px 14px; border-radius: 10px; font-size: 12px; background: #fff7e6; color: #d46b08; @@ -197,6 +201,32 @@ } .sync-progress__text { font-size: 11px; color: #bbb; } + /* 删除确认弹窗 */ + .delete-overlay { + position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1000; + display: none; align-items: center; justify-content: center; + } + .delete-overlay--show { display: flex; } + .delete-dialog { + width: 280px; background: #fff; border-radius: 16px; padding: 28px 24px 20px; + text-align: center; box-shadow: 0 12px 40px rgba(0,0,0,0.25); + animation: deleteDialogIn 0.25s ease; + } + @keyframes deleteDialogIn { + from { opacity: 0; transform: scale(0.9); } + to { opacity: 1; transform: scale(1); } + } + .delete-dialog__icon { font-size: 40px; margin-bottom: 12px; } + .delete-dialog__text { font-size: 15px; color: #333; margin-bottom: 20px; line-height: 1.5; } + .delete-dialog__actions { display: flex; gap: 12px; } + .delete-dialog__btn { + flex: 1; height: 40px; border: none; border-radius: 10px; + font-size: 15px; font-weight: 600; cursor: pointer; transition: opacity 0.15s; + } + .delete-dialog__btn:active { opacity: 0.8; } + .delete-dialog__btn--cancel { background: #f5f5f5; color: #666; } + .delete-dialog__btn--confirm { background: #ff4d4f; color: #fff; } + .home-indicator { height: 20px; display: flex; align-items: center; justify-content: center; background: #fff; flex-shrink: 0; @@ -250,8 +280,7 @@
男 · 45岁 · 175cm
- - +
@@ -260,13 +289,12 @@
李秀英 - 家庭成员 + 员工 已同步
女 · 43岁 · 162cm (他人添加)
- - +
@@ -281,7 +309,7 @@
男 · 12岁 · 152cm
- +
@@ -296,7 +324,7 @@
女 · 68岁 · 158cm
- +
@@ -468,6 +496,41 @@ showToast('已添加本人'); } + /* 删除成员确认 */ + var _deleteTarget = null; + + function confirmDelete(btn) { + _deleteTarget = btn; + var card = btn.closest('.member-card'); + var nameEl = card.querySelector('.member-name'); + var name = nameEl ? nameEl.textContent : '该成员'; + document.getElementById('deleteDialogText').textContent = '是否确认删除' + name + '?'; + document.getElementById('deleteOverlay').classList.add('delete-overlay--show'); + // 绑定确定按钮 + document.getElementById('deleteConfirmBtn').onclick = executeDelete; + } + + function closeDeleteDialog() { + document.getElementById('deleteOverlay').classList.remove('delete-overlay--show'); + _deleteTarget = null; + } + + function executeDelete() { + var target = _deleteTarget; + closeDeleteDialog(); + if (!target) return; + var card = target.closest('.member-card'); + if (card) { + card.classList.add('member-card--deleted'); + var syncEl = card.querySelector('.member-sync'); + if (syncEl) { + syncEl.textContent = '已删除 · 未同步'; + syncEl.className = 'member-sync member-sync--deleted'; + } + } + showToast('成员已删除'); + } + /* 同步成员至设备 */ function syncMembers() { var overlay = document.getElementById('syncOverlay'); @@ -514,5 +577,17 @@ + +
+
+
⚠️
+
是否确认删除该成员?
+
+ + +
+
+
+ diff --git a/other-module/bluetooth-scale-miniprogram/doc/PRD.md b/other-module/bluetooth-scale-miniprogram/doc/PRD.md new file mode 100644 index 0000000..c01f4ae --- /dev/null +++ b/other-module/bluetooth-scale-miniprogram/doc/PRD.md @@ -0,0 +1,569 @@ +# 蓝牙称小程序 产品需求文档 + +## 模块概述 + +蓝牙称小程序为员工提供智能蓝牙体重秤的配套管理能力,绑定与管理蓝牙体脂秤设备、WiFi配网、多成员管理、体脂测量数据查看与趋势分析、个性化信息维护等功能。员工可通过小程序完成从设备绑定到日常称重的完整闭环,同时支持家庭成员共用一台设备。 + +### 页面导航结构 + +``` +蓝牙称小程序 +├── 登录页(微信一键登录) +├── 完善个人信息(新用户首次) +└── 主页(底部 4 个 Tab) + ├── 首页 Tab:设备概览 + 最近测量数据展示 + │ └── 详细报告 + ├── 设备 Tab:设备列表与管理 + │ ├── 搜索设备 → WiFi连接 + │ ├── 成员管理 → 添加成员 + │ ├── 数据补传弹窗 + │ ├── 连接设备弹窗 + │ ├── 取消配对确认弹窗 + │ └── 运维模式(连续点击标题5次进入) + ├── 数据 Tab:体脂数据记录与统计 + │ ├── 切换用户弹窗 + │ └── 详细报告 + └── 我的 Tab:个人信息与帮助 + ├── 个人信息查看 → 完善个人信息(编辑模式) + ├── 帮助中心 → 帮助详情 + └── 退出登录 +``` + +--- + +## 页面清单 + +### 登录与信息完善 + +| 序号 | 页面/弹窗 | 文件 | 类型 | +|------|-----------|------|------| +| 1 | 登录页 | index.html | 页面 | +| 2 | 完善个人信息 | profile-complete.html | 页面 | + +### 首页 + +| 序号 | 页面/弹窗 | 文件 | 类型 | +|------|-----------|------|------| +| 3 | 主页(首页Tab) | main.html#tab-home | 页面(Tab内页面) | + +### 设备管理 + +| 序号 | 页面/弹窗 | 文件 | 类型 | +|------|-----------|------|------| +| 4 | 主页(设备Tab) | main.html#tab-device | 页面(Tab内页面) | +| - | 主页(设备Tab-未绑定空状态) | main.html#tab-device | 页面(状态变体) | +| 5 | 搜索设备 | search-device.html | 页面 | +| 6 | WiFi连接 | wifi-connect.html | 页面 | +| 7 | 成员管理 | device-members.html | 页面 | +| - | 成员管理(B2空状态-0成员) | device-members.html?device=b2 | 页面(状态变体) | +| - | 同步成员至设备弹窗 | device-members.html(内嵌弹窗) | 弹窗 | +| - | 同步成员至设备弹窗(已完成态) | device-members.html(内嵌弹窗) | 弹窗(状态变体) | +| - | 删除成员确认弹窗 | device-members.html(内嵌弹窗) | 弹窗 | +| 8 | 添加成员 | add-member.html | 页面 | +| - | 连接设备弹窗 | main.html(内嵌弹窗) | 弹窗 | +| - | 取消配对确认弹窗 | main.html(内嵌弹窗) | 弹窗 | +| - | 数据补传弹窗 | main.html(内嵌弹窗) | 弹窗 | +| - | 数据补传弹窗(再次补传-已上传态) | main.html(内嵌弹窗) | 弹窗(状态变体) | + +### 数据查看 + +| 序号 | 页面/弹窗 | 文件 | 类型 | +|------|-----------|------|------| +| 9 | 主页(数据Tab) | main.html#tab-data | 页面(Tab内页面) | +| - | 切换用户弹窗 | main.html(内嵌弹窗) | 弹窗 | +| 10 | 详细报告 | data-detail.html | 页面 | + +### 我的 + +| 序号 | 页面/弹窗 | 文件 | 类型 | +|------|-----------|------|------| +| 11 | 主页(我的Tab) | main.html#tab-me | 页面(Tab内页面) | +| 12 | 个人信息 | profile.html | 页面 | +| 13 | 帮助中心 | help-center.html | 页面 | +| 14 | 帮助详情 | help-detail.html | 页面 | + +--- + +## 逐页说明 + +--- + +## 一、登录与信息完善 + +### 1. 登录页(index.html) + +![页面截图](screenshots/index.jpg) + +**功能说明:** 蓝牙称小程序启动入口,微信一键登录。 + +**主要UI元素:** +- 品牌Logo区域 +- 功能亮点展示(精准称重、趋势分析、多成员管理) +- 微信一键登录按钮 + +**业务规则:** +- 首次登录后若无个人信息,跳转至完善个人信息页面 +- 已完善信息的老用户,登录后直接进入主页 + +**交互说明:** +- 点击"微信一键登录"按钮,进行微信授权,成功后跳转到完善个人信息页面 + +--- + +### 2. 完善个人信息(profile-complete.html) + +![页面截图](screenshots/profile-complete.jpg) + +**功能说明:** 新用户首次登录后完善个人基本信息,用于精准计算体脂数据。 + +**主要UI元素:** +- 提示条:"请完整填写信息,用于精准计算体脂数据" +- 表单:姓名(必填)、身份证(必填,输入后自动识别性别和年龄)、性别(根据身份证自动识别)、年龄(根据身份证自动识别)、身高(必填,cm) + +**业务规则:** +- 身份证输完后,自动解析性别和出生年份计算年龄 +- 如身份证存在于长庆系统,则需要将姓名和身份证做校验匹配,必须保持一致才行,如不一致,弹窗提示“当前身份证与姓名信息不一致,请重新填写” + +**交互说明:** +- 输入身份证号后自动填充性别和年龄 +- 点击"完成并进入首页"保存信息并跳转到主页 + +--- + +## 二、主页 + +主页采用底部4个Tab(首页/设备/数据/我的)布局,每个Tab为独立内容面板,通过Tab切换显示。 + +--- + +### 3. 主页-首页Tab(main.html#tab-home) + +![页面截图](screenshots/main.jpg) + +**功能说明:** 展示当前用户的设备概览和最近一次测量数据,包括体重、BMI、体脂率及核心身体成分指标。 + +**主要UI元素:** +- 绿色头部(程序信息卡片) +- 个人信息卡片(姓名、身高、年龄、性别) +- 最近测量卡片: + - 标题栏("最近测量" + "详细报告 ›"链接) + - 测量时间 + - 体重数字 + - 较上次变化量(绿色↓/红色↑/无变化不显示) + - BMI和体脂率并列展示 + - 详细数据网格(体脂肪量、体水分量、蛋白质量) + +**业务规则:** +- BMI参考范围:<18.5消瘦、18.5≤BMI<24正常、24≤BMI<28超重、≥28肥胖 +- 体脂率等级标准: + - 男性:18-39岁(偏瘦<11%、标准11-20%、偏胖20-25%、肥胖>25%);40-59岁(偏瘦<12%、标准12-21%、偏胖21-26%、肥胖>26%);60岁以上(偏瘦<14%、标准14-23%、偏胖23-28%、肥胖>28%) + - 女性:18-39岁(偏瘦<21%、标准21-32%、偏胖32-37%、肥胖>37%);40-59岁(偏瘦<23%、标准23-34%、偏胖34-39%、肥胖>39%);60岁以上(偏瘦<25%、标准25-36%、偏胖36-41%、肥胖>41%) +- 首次使用无测量数据时显示空状态 + +**交互说明:** +- 点击"详细报告"跳转到详细报告页面 + +--- + +### 4. 主页-设备Tab(main.html#tab-device) + +![页面截图](screenshots/main-device.jpg) + +**功能说明:** 管理已绑定的蓝牙体脂秤设备,支持查看设备状态(已连接/未连接)、连接设备、WiFi配网、成员管理、数据补传、取消配对等操作。未绑定设备时展示空状态引导绑定。 + +**主要UI元素:** +- 绿色头部(同首页Tab,标题连续点击五次,触发运维模式) +- 运维模式标记(标题右上角红色徽章"运维模式" + "关闭运维模式"按钮) +- 未绑定空状态:设备图标 + "请绑定设备"文案 + "绑定设备"按钮 +- 已配对设备列表: + - 设备卡片(图标、名称、型号、设备编码、连接状态徽章、取消配对按钮) + - 操作按钮组:设备WIFI / 成员管理(人数) / 数据补传 / 连接设备 +- "+ 添加设备"按钮 + +**业务规则:** +- 连续点击设备Tab标题5次进入运维模式,显示"运维模式"文字 、 "关闭运维模式"按钮、"取消全部配对"按钮 +- 未连接设备显示"连接设备"、“成员管理”按钮,已连接设备显示“设备WIFI”、“成员管理”、"数据补传"按钮 + +**交互说明:** +- 未绑定状态:"绑定设备"按钮跳转到搜索设备页面 +- 已绑定设备:设备WIFI跳转到WiFi连接页面;成员管理跳转到成员管理页面;数据补传打开数据补传弹窗;连接设备打开连接弹窗 +- 取消配对:点击单个设备的取消配对按钮,弹出二次确认弹窗,确认后从列表中删除该设备;若删除后无剩余设备则恢复空状态 +- 运维模式-取消全部配对:清除所有配对,弹出二次确认弹窗,确认后从列表中删除所有设备。 + +**状态变体 — 未绑定空状态:** + +![空状态截图](screenshots/main-device-empty.jpg) + +**功能说明:** 设备 Tab 在未绑定任何设备时展示空状态引导页。点击按钮跳转至搜索设备页面。 + +--- + +#### 连接设备弹窗(main.html 内嵌) + +![弹窗截图](screenshots/main-connect-dialog.jpg) + +**功能说明:** 点击未连接设备的"连接设备"按钮后,进行蓝牙设备连接过程。 + +**主要UI元素:** +- 弹窗loading + +**交互说明:** +- 连接成功后,关闭弹窗,失败则提示错误信息弹窗。 + +--- + +#### 数据补传弹窗(main.html 内嵌) + +![弹窗截图](screenshots/main-retransmission-dialog.jpg) +![弹窗截图](screenshots/main-retransmission-done.jpg) + +点击已连接设备的"数据补传"按钮后弹出: +- 1:获取设备本地未上传的数据,弹窗提示“正在上传数据,请稍后...”,弹窗不允许点击空白时关闭 +- 2:获取到之后上传数据,弹窗提示“正在上传数据,请稍后...”(弹窗不允许点击空白时关闭),上传成功后关闭弹窗,toast提示“数据已全部上传” +- 3:未获取到提示“设备本地数据已全部上传” + + +--- + +#### 取消配对确认弹窗(main.html 内嵌) + +**功能说明:** 点击设备卡片右上角"取消配对"按钮后弹出二次确认弹窗,防止误操作导致设备解绑。 + +**主要UI元素:** +- 确认文字:"是否取消配对{设备名称}设备?"(设备名称根据点击的设备动态显示) +- 取消按钮(灰色)+ 确定按钮(红色) + +**业务规则:** +- 弹窗标题文字根据被点击的设备动态拼接,格式为"是否取消配对XXXXX设备?" +- 确认后从设备列表中移除该设备卡片 +- 若移除后设备列表为空,自动切换至未绑定空状态 +- 取消按钮关闭弹窗,不做任何操作 + +**交互说明:** +- 点击"确定" → 关闭弹窗,删除对应设备卡片,显示Toast"设备「{设备名称}」已取消配对" +- 点击"取消" → 关闭弹窗,不做任何操作 + +--- + +### 5. 搜索设备(search-device.html) + +![页面截图](screenshots/search-device.jpg) + +**功能说明:** 通过蓝牙搜索附近可用的体脂秤设备,搜索过程中显示脉冲动画,搜索完成后列出发现的设备。 + +**主要UI元素:** +- 搜索动画区域(设备图标 + 三层脉冲波纹动画) +- 搜索中提示:"搜索设备中…" +- 操作提示:"请确保手机蓝牙已开启,设备处于开启状态,手机尽量靠近设备(2米以内)" +- 搜索完成后的设备列表: + - 重新搜索按钮 + - 设备卡片(设备图标、名称、信号强度、连接状态) +- 已连接的设备显示"已连接"徽章 +- 未连接的设备显示箭头 + +**交互说明:** +- 页面自动开启搜索,搜索后自动显示结果,脉冲动画停止 +- 点击已连接设备 → 直接跳转到设备Tab +- 点击未连接设备 → 完成蓝牙连接操作,连接成功后跳转到WiFi连接页面进行配网 +- 点击"重新搜索"再次开启搜索 + +--- + +### 6. WiFi连接(wifi-connect.html) + +![页面截图](screenshots/wifi-connect.jpg) + +**功能说明:** 为蓝牙体脂秤配置WiFi网络连接,支持从搜索设备进入(首次配网)和从已配对设备进入(修改WiFi)两种场景。 + +**主要UI元素:** +- 导航栏(标题"WiFi连接",搜索设备页面连接蓝牙后进入时显示"跳过"按钮) +- 搜索WiFi动画(📡图标 + "正在搜索附近 WiFi…") +- WiFi列表: + - 网络名称、安全类型 + - 已连接网络显示 ✓ 标记和绿色边框 + - 受密码保护的网络显示🔒标记 + +**业务规则:** +- 从首页设备页进入:跳过搜索动画直接显示WiFi列表,隐藏"跳过"按钮 +- 从搜索设备进入:搜索动画后显示WiFi列表 +- "跳过"按钮点击后直接返回设备Tab + +**交互说明:** +- 点击WiFi网络 → 密码输入页面,点击连接按钮,进行WiFi连接,成功后跳转到设备Tab +- 点击"刷新" → 重新搜索刷新WiFi列表 +- 点击"跳过" → 直接跳转到设备Tab(不配置WiFi) + +--- + +### 7. 成员管理(device-members.html) + +![页面截图](screenshots/device-members.jpg) + +**功能说明:** 管理蓝牙体脂秤设备的测量成员列表,支持成员信息的增删改查、成员信息同步到设备。 + +**主要UI元素:** +- 设备信息卡片(设备图标、名称、型号、设备编码、连接状态) +- 已录入成员标题(含容量显示如"已录入成员(4/10)") +- 同步按钮("同步成员至设备",设备未连接时禁用并置灰) +- 同步提示条(当前存在未同步的成员信息,"当前成员信息未同步至设备,请在连接设备的状态下,点击同步按钮完成信息同步") +- 成员卡片: + - 头像(按性别分类着色:男=蓝色、女=粉色) + - 姓名 + 身份标签(本人/员工/家庭成员) + - 同步状态(已同步=绿色、未同步=红色) + - 基本信息(性别、年龄、身高) + - 操作按钮(编辑/删除) +- 空状态("暂无成员" + "请添加成员以使用设备测量"文字) +- 按钮:"一键添加本人"按钮 + "添加新成员"按钮 + +**业务规则:** +- 设备成员容量上限为10人 +- 本人成员置顶显示,隐藏编辑按钮 +- 他人添加的成员标注"(他人添加)"提示 +- 删除成员后卡片变为半透明,"已删除 · 未同步"状态需执行同步才会从设备端移除 +- 设备未连接时,同步按钮禁用并置灰 +- 员工类型成员时,隐藏编辑按钮 +- 未存在身份类型为本人的成员时,显示“一键添加本人”按钮 +- 运维模式下:同步成员设备时,不计入关联处理,该成员不与运维人员进行实际性关联,不属于“他人添加”标记 +- 所有同步设备操作记录都需留存,操作人、操作时间、成员数据信息、设备信息(设备编码) + +**交互说明:** +- 点击"同步成员至设备" → 打开同步进度弹窗 +- 点击"添加新成员" → 跳转到添加成员页面 +- 点击"一键添加本人" → 自动添加当前个人信息的成员,刷新列表,更新成员计数 +- 点击删除按钮 → 打开删除确认弹窗 +- 点击编辑按钮 → 提示"编辑功能开发中" +- 同步弹窗进度条动画完成后自动关闭并提示 + +**成员空状态:** + +![空状态截图](screenshots/device-members-empty.jpg) + +当设备成员数为 0 时(,页面展示空状态:"暂无成员" + "请添加成员以使用设备测量"文案,底部双按钮"一键添加本人"和"添加新成员"。 + +--- + +#### 同步成员至设备弹窗(device-members.html 内嵌) + + +![弹窗截图](screenshots/device-members-sync-dialog.jpg) + +点击"同步成员至设备"后进行设备同步成员操作,并弹窗提示,带进度条,显示"正在同步信息,请勿离开...",弹窗不允许点击空白时关闭 +同步成功后,关闭弹窗,toast提示“同步完成”,刷新列表数据 + + +--- + +#### 删除成员确认弹窗(device-members.html 内嵌) + +![弹窗截图](screenshots/device-members-delete-dialog.jpg) + +**功能说明:** 删除成员前的二次确认弹窗,防止误操作。 + +**主要UI元素:** +- ⚠️ 图标 +- 确认文字"是否确认删除{成员名}?",如果是他人添加,则确认文字为:‘XXXX’成员为他人添加,请确认是否删除 +- 取消按钮 + 确定按钮(红色) + +**交互说明:** +- 点击"确定" → 成员卡片变为半透明删除态,同步状态更新为"已删除 · 未同步" +- 点击"取消" → 关闭弹窗 + +--- + +### 8. 添加成员(add-member.html) + +![页面截图](screenshots/add-member.jpg) + +**功能说明:** 向设备添加新的测量成员,支持两种用户类型:员工(通过员工编号查询)和家庭成员(手动填写信息或从已有成员中选择)。 + +**主要UI元素:** +- 用户类型选择(员工 / 家庭成员) +- 员工表单: + - 员工编号输入 + "确认查询"按钮 + - 查询结果卡片(姓名、单位-部门、性别、年龄) + - 补充信息表单(身高必填、体重选填,员工有数据则自动填入) +- 家庭成员表单: + - "从已有成员中选择"按钮 + - 昵称(必填)、身份证(选填,填写后自动识别性别和出生年月) + - 性别选择(男女按钮)、出生年月(月份选择器,必填) + - 身高(必填,cm)、体重(选填,kg) +- 已有成员选择器弹窗(底部弹出,列出可选成员(本人添加过的当前设备外其他设备已录入的成员),点击选择后自动填充表单) + +**业务规则:** +- 员工类型:通过员工编号查询系统返回基本信息,身高和体重查询到数据后自动填入 +- 家庭成员类型:身份证填写后可自动解析性别和出生年月 +- 家庭成员可从"已有成员"中选择,快速填充当前设备外其他设备已录入的成员 + +**交互说明:** +- 点击用户类型Tab切换员工/家庭成员表单 +- 员工模式:输入编号后点击"确认查询"展示查询结果和补充表单 +- 家庭成员模式:点击"从已有成员中选择"打开底部成员选择器弹窗 +- 选择已有成员后自动填充昵称、性别、出生年月、身高、体重 +- 输入身份证自动解析性别和出生年月 +- 点击"保存用户信息" → 保存成功后Toast提示"保存成功!"并返回上一页 + +--- + +## 三、数据查看 + +### 9. 主页-数据Tab(main.html#tab-data) + +![页面截图](screenshots/main-data.jpg) + +**功能说明:** 展示当前用户的体重记录列表和统计摘要,支持切换查看不同成员的数据,以及按时间范围(近7日/近30日/近90日)筛选。 + +**主要UI元素:** +- 用户信息卡片(头像、姓名、身份类型、身高、年龄、性别 + "切换用户"按钮) +- 时间范围筛选(近7日/近30日/近90日 三个Tab) +- 统计卡片行(4格:最高体重/最低体重/平均体重/体重变化) +- 体重记录列表: + - 测量时间、体重数值、BMI + 体脂率 + - 体重变化箭头(▲上升红色/▼下降绿色/无变化不显示) + - 右箭头进入详情 + +**业务规则:** +- 倒序显示 + +**交互说明:** +- 点击"切换用户" → 打开成员选择弹窗,显示本人及本人添加的成员列表,选择后显示该成员的数据 +- 点击时间Tab(近7日/近30日/近90日)切换统计数据和记录列表 +- 点击记录条目 → 跳转到详细报告页面 + +--- + +#### 切换用户弹窗(main.html 内嵌) + +![弹窗截图](screenshots/main-member-modal.jpg) + +**功能说明:** 在数据Tab中切换查看不同家庭成员的数据,底部弹出成员列表供选择。 + +**主要UI元素:** +- 弹窗标题"切换用户" + 关闭按钮(×) +- 成员列表: + - 头像 + - 姓名 + 身份标签(本人/员工/家庭成员) + - 基本信息(性别、年龄、身高) + +**业务规则:** +- 显示本人及本人添加的成员列表 + +**交互说明:** +- 点击成员 → 关闭弹窗,Toast提示"已切换到「{姓名}」" + +--- + +### 10. 详细报告(data-detail.html) + +![页面截图](screenshots/data-detail.jpg) + +**功能说明:** 展示单次测量的完整身体成分报告,包含体重的核心指标、身体成分分析(水分、蛋白质、肌肉、骨骼、脂肪、细胞液)。 + +**主要UI元素:** +- 报告头部(绿色渐变背景): + - 测量时间 + - 体重数字大字展示 + - 标签(BMI状态如"正常"、较上次变化量) +- 基础指标(网格布局2列): + - 身高/体重/BMI(含状态标签)/基础代谢 + - 体脂肪量/体脂肪率(含状态标签) + - BMI彩色标尺 +- 水分与蛋白质(行布局): + - 体水分量/体水分率/蛋白质量/蛋白质率 +- 肌肉与骨骼: + - 体肌肉量/体肌肉率/体骨骼量 +- 脂肪分析: + - 皮下脂肪量/皮下脂肪率/除脂肪量 +- 细胞液: + - 细胞外液量/细胞外液率/细胞内液量/细胞内液率 +- 其他: + - 矿物质量 + +**业务规则:** +- 各项指标状态通过标准参考范围判断。体脂肪率等级结合性别和年龄动态计算 +- BMI参考范围:<18.5消瘦、18.5≤BMI<24正常、24≤BMI<28超重、≥28肥胖 +- 体脂率等级标准: + - 男性:18-39岁(偏瘦<11%、标准11-20%、偏胖20-25%、肥胖>25%);40-59岁(偏瘦<12%、标准12-21%、偏胖21-26%、肥胖>26%);60岁以上(偏瘦<14%、标准14-23%、偏胖23-28%、肥胖>28%) + - 女性:18-39岁(偏瘦<21%、标准21-32%、偏胖32-37%、肥胖>37%);40-59岁(偏瘦<23%、标准23-34%、偏胖34-39%、肥胖>39%);60岁以上(偏瘦<25%、标准25-36%、偏胖36-41%、肥胖>41%) + +**交互说明:** +- 点击返回按钮返回主页 +- 页面为纯展示,无可交互元素 + +--- + +## 四、我的 + +### 11. 主页-我的Tab(main.html#tab-me) + +![页面截图](screenshots/main-me.jpg) + +**功能说明:** 个人中心入口,展示用户基本信息,提供个人信息查看、帮助中心和退出登录等功能的入口。 + +**主要UI元素:** +- 用户信息卡片(头像、姓名、单位-部门) +- 菜单列表: + - 个人信息 + - 帮助中心 +- 退出登录按钮 + +**业务规则:** +- 单位部门不存在则隐藏,姓名和头像垂直居中 + +**交互说明:** +- 点击"个人信息" → 跳转到个人信息查看页面 +- 点击"帮助中心" → 跳转到帮助中心页面 +- 点击"退出登录" → 弹出二次确认弹窗,确定后跳转到登录页 + +--- + +### 12. 个人信息(profile.html) + +![页面截图](screenshots/profile.jpg) + +**功能说明:** 查看当前用户的详细个人信息。 + +**主要UI元素:** +- 头像展示 +- 信息列表: + - 姓名/身份证/性别/年龄/单位/部门/身高/体重 + +**交互说明:** +- 点击返回按钮返回我的Tab + +--- + +### 13. 帮助中心(help-center.html) + +![页面截图](screenshots/help-center.jpg) + +**功能说明:** 展示常见问题FAQ列表,支持按分类筛选查看。 + +**主要UI元素:** +- 分类标签(全部/连接配对/使用测量/数据管理) +- FAQ列表: + - 问题标题 + - 右箭头进入详情 + +**交互说明:** +- 点击分类标签筛选列表 +- 点击列表 → 跳转到帮助详情页面 + +--- + +### 14. 帮助详情(help-detail.html) + +![页面截图](screenshots/help-detail.jpg) + +**功能说明:** 展示单条的详细解答内容 + +**主要UI元素:** +- 问题标题 +- 答案内容(富文本) + +**交互说明:** +- 点击返回按钮返回帮助中心页面 + +--- + + + diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/add-member.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/add-member.jpg new file mode 100644 index 0000000..c29a894 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/add-member.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/data-detail.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/data-detail.jpg new file mode 100644 index 0000000..98bfef7 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/data-detail.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-delete-dialog.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-delete-dialog.jpg new file mode 100644 index 0000000..cf2b93c Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-delete-dialog.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-empty.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-empty.jpg new file mode 100644 index 0000000..c4f4dad Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-empty.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-sync-dialog.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-sync-dialog.jpg new file mode 100644 index 0000000..a945906 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-sync-dialog.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-sync-done.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-sync-done.jpg new file mode 100644 index 0000000..2a3c3d7 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members-sync-done.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members.jpg new file mode 100644 index 0000000..61d2948 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/device-members.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/help-center.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/help-center.jpg new file mode 100644 index 0000000..dc30bab Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/help-center.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/help-detail.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/help-detail.jpg new file mode 100644 index 0000000..998908c Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/help-detail.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/index.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/index.jpg new file mode 100644 index 0000000..4b40d59 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/index.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-connect-dialog.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-connect-dialog.jpg new file mode 100644 index 0000000..713f056 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-connect-dialog.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-data.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-data.jpg new file mode 100644 index 0000000..1baa30a Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-data.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-device-empty.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-device-empty.jpg new file mode 100644 index 0000000..cf06e7f Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-device-empty.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-device.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-device.jpg new file mode 100644 index 0000000..adeaaee Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-device.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-me.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-me.jpg new file mode 100644 index 0000000..196ad6b Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-me.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-member-modal.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-member-modal.jpg new file mode 100644 index 0000000..c29cf9f Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-member-modal.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-retransmission-dialog.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-retransmission-dialog.jpg new file mode 100644 index 0000000..13d6e45 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-retransmission-dialog.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-retransmission-done.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-retransmission-done.jpg new file mode 100644 index 0000000..2a70e6d Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main-retransmission-done.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/main.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main.jpg new file mode 100644 index 0000000..2ad7299 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/main.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/profile-complete.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/profile-complete.jpg new file mode 100644 index 0000000..88048d4 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/profile-complete.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/profile.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/profile.jpg new file mode 100644 index 0000000..1ba69ac Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/profile.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/search-device.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/search-device.jpg new file mode 100644 index 0000000..cd85a80 Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/search-device.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/doc/screenshots/wifi-connect.jpg b/other-module/bluetooth-scale-miniprogram/doc/screenshots/wifi-connect.jpg new file mode 100644 index 0000000..732054b Binary files /dev/null and b/other-module/bluetooth-scale-miniprogram/doc/screenshots/wifi-connect.jpg differ diff --git a/other-module/bluetooth-scale-miniprogram/help-center.html b/other-module/bluetooth-scale-miniprogram/help-center.html index 92ef310..a6ac905 100644 --- a/other-module/bluetooth-scale-miniprogram/help-center.html +++ b/other-module/bluetooth-scale-miniprogram/help-center.html @@ -68,11 +68,6 @@ .faq-item:last-child { border-radius: 0 0 14px 14px; border-bottom: none; } .faq-item:only-child { border-radius: 14px; } .faq-item:active { background: #fafafa; } - .faq-item__icon { - width: 36px; height: 36px; border-radius: 10px; - background: #f0faf5; display: flex; align-items: center; - justify-content: center; font-size: 16px; flex-shrink: 0; - } .faq-item__info { flex: 1; min-width: 0; } .faq-item__title { font-size: 14px; font-weight: 500; color: #1a1a1a; } .faq-item__arrow { font-size: 16px; color: #ccc; } @@ -109,42 +104,36 @@
-
📡
如何连接蓝牙设备?
-
📶
设备无法连接WiFi怎么办?
-
👥
如何添加和管理成员?
-
📊
测量数据不准确如何校准?
-
🔄
数据补传功能如何使用?
-
🔋
设备电量消耗过快?
diff --git a/other-module/bluetooth-scale-miniprogram/main.html b/other-module/bluetooth-scale-miniprogram/main.html index 86e8511..49abd24 100644 --- a/other-module/bluetooth-scale-miniprogram/main.html +++ b/other-module/bluetooth-scale-miniprogram/main.html @@ -160,6 +160,18 @@ background: #e8f8ef; color: #07c160; border-radius: 6px; padding: 2px 8px; font-size: 10px; font-weight: 500; display: inline-block; } + .tag-blue { + background: #e6f7ff; color: #1890ff; border-radius: 6px; + padding: 2px 8px; font-size: 10px; font-weight: 500; display: inline-block; + } + .tag-orange { + background: #fff7e6; color: #fa8c16; border-radius: 6px; + padding: 2px 8px; font-size: 10px; font-weight: 500; display: inline-block; + } + .tag-red { + background: #fff2f0; color: #ff4d4f; border-radius: 6px; + padding: 2px 8px; font-size: 10px; font-weight: 500; display: inline-block; + } /* 空状态 */ .empty-state { @@ -329,7 +341,7 @@ } .record-change--up { color: var(--danger); } .record-change--down { color: var(--success); } - .record-change--flat { color: var(--text-placeholder); } + .record-change--flat { display: none; } .record-arrow { font-size: 16px; color: #ccc; } /* ===== 我的 Tab 样式 ===== */ @@ -384,6 +396,28 @@ } .toast--show { opacity: 1; transform: translateX(-50%) translateY(0); } + /* 确认弹窗 */ + .confirm-overlay { + position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1000; + display: none; align-items: center; justify-content: center; + } + .confirm-overlay--show { display: flex; } + .confirm-dialog { + width: 280px; background: #fff; border-radius: 16px; padding: 28px 24px 20px; + text-align: center; box-shadow: 0 12px 40px rgba(0,0,0,0.25); + animation: connectDialogIn 0.3s ease; + } + .confirm-dialog__title { font-size: 16px; font-weight: 600; color: #1a1a1a; margin-bottom: 12px; line-height: 1.5; } + .confirm-dialog__actions { display: flex; gap: 12px; margin-top: 20px; } + .confirm-dialog__btn { + flex: 1; height: 40px; border: none; border-radius: 10px; font-size: 15px; + font-weight: 600; cursor: pointer; transition: all 0.2s; + } + .confirm-dialog__btn--cancel { background: #f5f5f5; color: #666; } + .confirm-dialog__btn--cancel:active { background: #e8e8e8; } + .confirm-dialog__btn--confirm { background: var(--danger); color: #fff; } + .confirm-dialog__btn--confirm:active { background: #d9363e; } + /* 连接弹窗 */ .connect-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1000; @@ -461,13 +495,13 @@
BMI
23.8
-
正常范围
+
正常
体脂率
22.1%
-
标准
+
标准
@@ -733,7 +767,6 @@
张建国
-
男 · 45岁
健康科技公司 · 技术部-研发组
@@ -992,9 +1025,43 @@ showToast('已取消全部配对'); } + var _unpairTarget = null; + var _deviceNameMap = { 's1': '家庭蓝牙体脂秤 S1', 'b2': '办公蓝牙体重秤 B2' }; + function unpairDevice(deviceId) { - // 单个设备取消配对(模拟:提示后不做实际移除,保持列表展示) - showToast('设备「' + (deviceId === 's1' ? '家庭蓝牙体脂秤 S1' : '办公蓝牙体重秤 B2') + '」已取消配对'); + _unpairTarget = deviceId; + var name = _deviceNameMap[deviceId] || '未知'; + document.getElementById('confirmDialogTitle').textContent = '是否取消配对' + name + '设备?'; + document.getElementById('confirmOverlay').classList.add('confirm-overlay--show'); + } + + function confirmUnpair() { + var deviceId = _unpairTarget; + if (!deviceId) return; + // 从 DOM 中移除对应设备项 + var items = document.querySelectorAll('.device-item'); + for (var i = 0; i < items.length; i++) { + var btn = items[i].querySelector('.device-item__unpair'); + if (btn && btn.getAttribute('onclick').indexOf("'" + deviceId + "'") !== -1) { + items[i].remove(); + break; + } + } + // 如果列表中已无设备,恢复空状态 + var remaining = document.querySelectorAll('.device-item'); + if (remaining.length === 0) { + document.getElementById('deviceEmpty').style.display = ''; + document.getElementById('devicePaired').style.display = 'none'; + sessionStorage.removeItem('devicePaired'); + } + var name = _deviceNameMap[deviceId] || '未知'; + showToast('设备「' + name + '」已取消配对'); + closeConfirmDialog(); + } + + function closeConfirmDialog() { + document.getElementById('confirmOverlay').classList.remove('confirm-overlay--show'); + _unpairTarget = null; } /* ===== 成员选择弹窗 ===== */ @@ -1008,6 +1075,35 @@ closeMemberModal(); showToast('已切换到「' + name + '」'); } + + /* ===== 体脂率等级判断 ===== */ + function getBodyFatLevel(sex, age, bf) { + // 日本肥胖学会分龄分性别标准 + var thresholds; + if (sex === 'male' || sex === '男') { + if (age < 40) thresholds = { thin: 11, fit: 20, heavy: 25 }; + else if (age < 60) thresholds = { thin: 12, fit: 21, heavy: 26 }; + else thresholds = { thin: 14, fit: 23, heavy: 28 }; + } else { + if (age < 40) thresholds = { thin: 21, fit: 32, heavy: 37 }; + else if (age < 60) thresholds = { thin: 23, fit: 34, heavy: 39 }; + else thresholds = { thin: 25, fit: 36, heavy: 41 }; + } + if (bf < thresholds.thin) return { label: '偏瘦', cssClass: 'tag-blue' }; + if (bf <= thresholds.fit) return { label: '标准', cssClass: 'tag-green' }; + if (bf <= thresholds.heavy) return { label: '偏胖', cssClass: 'tag-orange' }; + return { label: '肥胖', cssClass: 'tag-red' }; + } + + // 初始化首页体脂率等级标签(张建国:男,45岁,体脂率22.1%) + (function() { + var tag = document.getElementById('homeFatLevelTag'); + if (tag) { + var level = getBodyFatLevel('male', 45, 22.1); + tag.textContent = level.label; + tag.className = level.cssClass; + } + })(); @@ -1028,5 +1124,16 @@ + +
+
+
是否取消配对设备?
+
+ + +
+
+
+ diff --git a/other-module/bluetooth-scale-miniprogram/profile.html b/other-module/bluetooth-scale-miniprogram/profile.html index 1b1c35e..d17ba70 100644 --- a/other-module/bluetooth-scale-miniprogram/profile.html +++ b/other-module/bluetooth-scale-miniprogram/profile.html @@ -69,13 +69,6 @@ .info-label { font-size: 14px; color: var(--text-secondary); width: 72px; flex-shrink: 0; } .info-value { flex: 1; font-size: 14px; color: var(--text-primary); text-align: right; } - /* 修改按钮 */ - .edit-btn { - width: 100%; height: 44px; border: 1px solid var(--primary); border-radius: 12px; - background: #fff; color: var(--primary); font-size: 15px; font-weight: 600; - cursor: pointer; margin-top: 24px; - } - .home-indicator { height: 20px; display: flex; align-items: center; justify-content: center; background: #fff; flex-shrink: 0; @@ -112,9 +105,10 @@
单位健康科技公司
部门技术部-研发组
身高175cm
+
体重72kg
- +
diff --git a/启动服务器.bat b/启动服务器.bat deleted file mode 100644 index e1bf779..0000000 --- a/启动服务器.bat +++ /dev/null @@ -1,72 +0,0 @@ -@echo off -chcp 65001 >nul -title 健康CQ原型 - 本地服务器 -cd /d "%~dp0" - -echo ============================================ -echo 健康CQ升级项目 · 高保真交互原型 -echo ============================================ -echo. -echo [检测] 检查端口 8080 ... - -:: ── 检查端口 8080 是否已被占用 ── -netstat -ano 2>nul | findstr ":8080" | findstr "LISTENING" >nul -if %errorlevel% equ 0 ( - echo [警告] 端口 8080 已被占用! - echo. - echo 请先关闭占用 8080 端口的程序,或者: - echo 1. 任务管理器关闭相关进程 - echo 2. 运行: netstat -ano ^| findstr :8080 查看 PID - echo 3. 运行: taskkill /PID ^ /F 强制结束 - - :: 尝试直接打开已有的服务 - echo. - echo [尝试] 直接打开浏览器访问 http://localhost:8080/ ... - start http://localhost:8080/ - pause - exit /b 0 -) - -:: ── 优先 Python(最稳定,无需联网)── -where python >nul 2>nul -if %errorlevel% equ 0 ( - echo [启动] 使用 Python 启动 HTTP 服务器(端口 8080)... - echo. - echo ★ 服务器运行中,请勿关闭本窗口 ★ - echo 访问地址:http://localhost:8080/ - echo 按 Ctrl+C 停止服务器 - echo ============================================ - echo. - python -m http.server 8080 - goto end -) - -:: ── 备选 npx serve(需联网下载)── -where npx >nul 2>nul -if %errorlevel% equ 0 ( - echo [启动] 使用 npx serve 启动服务器(端口 8080)... - echo 首次运行可能需要下载依赖,请稍候... - echo. - echo ★ 服务器运行中,请勿关闭本窗口 ★ - echo 访问地址:http://localhost:8080/ - echo 按 Ctrl+C 停止服务器 - echo ============================================ - echo. - npx --yes serve . -p 8080 --no-clipboard - goto end -) - -:: ── 都不可用 ── -echo [错误] 未找到 Python 或 Node.js! -echo. -echo 请安装以下任一工具: -echo · Python 3: https://www.python.org/downloads/ -echo · Node.js: https://nodejs.org/ -echo. -pause -exit /b 1 - -:end -echo. -echo 服务器已停止。 -pause