[AI Generated]: feat(*): 新增 lefu 蓝牙服务层、mock 业务数据层及 request 请求封装,接入各页面

This commit is contained in:
17792275749
2026-05-13 16:18:14 +08:00
parent 38d6f0867a
commit 3f12e34afd
18 changed files with 1222 additions and 540 deletions
+69
View File
@@ -0,0 +1,69 @@
/** 时间范围 */
export type TimeRange = '7d' | '30d' | '3m'
/** 单条测量记录 */
export interface RecordItem {
id: string
/** 格式 YYYY.MM.DD HH:mm */
time: string
weight: number
bmi: number
/** 体脂率(%) */
bodyFat: number
}
/** 统计指标 */
export interface StatsData {
maxWeight: number
minWeight: number
avgWeight: number
/** 体重变化(kg,正=增重,负=减轻) */
weightDiff: number
}
/** 全量 mock 记录(最近 3 个月数据,按时间倒序) */
const ALL_RECORDS: RecordItem[] = [
{ id: 'r-001', time: '2026.05.12 08:12', weight: 68.2, bmi: 22.0, bodyFat: 18.5 },
{ id: 'r-002', time: '2026.05.11 21:30', weight: 68.5, bmi: 22.1, bodyFat: 18.7 },
{ id: 'r-003', time: '2026.05.10 08:05', weight: 68.8, bmi: 22.3, bodyFat: 18.9 },
{ id: 'r-004', time: '2026.05.09 07:58', weight: 69.0, bmi: 22.4, bodyFat: 19.0 },
{ id: 'r-005', time: '2026.05.08 22:10', weight: 69.3, bmi: 22.5, bodyFat: 19.2 },
{ id: 'r-006', time: '2026.05.07 08:20', weight: 69.5, bmi: 22.6, bodyFat: 19.3 },
{ id: 'r-007', time: '2026.05.06 08:00', weight: 70.0, bmi: 22.7, bodyFat: 19.5 },
{ id: 'r-008', time: '2026.04.30 08:10', weight: 70.3, bmi: 22.8, bodyFat: 19.7 },
{ id: 'r-009', time: '2026.04.20 07:45', weight: 71.0, bmi: 23.0, bodyFat: 20.0 },
{ id: 'r-010', time: '2026.04.10 08:30', weight: 71.8, bmi: 23.2, bodyFat: 20.3 },
{ id: 'r-011', time: '2026.03.28 08:15', weight: 72.5, bmi: 23.5, bodyFat: 20.7 },
{ id: 'r-012', time: '2026.03.15 09:00', weight: 73.2, bmi: 23.7, bodyFat: 21.0 },
{ id: 'r-013', time: '2026.03.01 08:05', weight: 73.8, bmi: 23.9, bodyFat: 21.3 },
]
/** 各时间范围截取数量 */
const RANGE_COUNTS: Record<TimeRange, number> = {
'7d': 7,
'30d': 10,
'3m': 13,
}
/**
* 按时间范围获取 mock 记录列表
*/
export function getMockRecords(range: TimeRange): RecordItem[] {
return ALL_RECORDS.slice(0, RANGE_COUNTS[range])
}
/**
* 根据记录列表计算统计指标
*/
export function calcStats(records: RecordItem[]): StatsData {
if (!records.length) {
return { maxWeight: 0, minWeight: 0, avgWeight: 0, weightDiff: 0 }
}
const weights = records.map(r => r.weight)
const maxWeight = Math.max(...weights)
const minWeight = Math.min(...weights)
const avgWeight = parseFloat((weights.reduce((a, b) => a + b, 0) / weights.length).toFixed(1))
// 最新 - 最旧
const weightDiff = parseFloat((weights[0] - weights[weights.length - 1]).toFixed(1))
return { maxWeight, minWeight, avgWeight, weightDiff }
}
+40
View File
@@ -0,0 +1,40 @@
/** 最近一次测量记录 */
export interface WeightRecord {
/** 体重整数部分 */
weight: number
/** 体重小数部分,含小数点,如 ".20" */
weightDecimal: string
/** 测量时间显示,如 "今日 07:30" */
date: string
/** 与上次相比差值(负=减轻,正=增重) */
diff: number
/** 身高(cm) */
height: number
/** BMI 值 */
bmi: number
/** BMI 评级标签 */
bmiLabel: string
/** 标准体重(kg) */
stdWeight: number
/** 体脂率(%) */
bodyFat: number
/** 体脂肪(kg) */
bodyFatMass: number
/** 基础代谢(kcal) */
bmr: number
}
/** Mock 最近一次测量记录 */
export const mockLatestRecord: WeightRecord = {
weight: 68,
weightDecimal: '.20',
date: '今日 07:30',
diff: -0.3,
height: 176,
bmi: 22.4,
bmiLabel: '标准',
stdWeight: 67.2,
bodyFat: 22.3,
bodyFatMass: 15.2,
bmr: 1652,
}
+69
View File
@@ -0,0 +1,69 @@
/** 成员项(与 equipmentMember / data 页面共享结构) */
export interface MemberItem {
id: string
name: string
gender: '男' | '女'
age: number
/** 身高(cm) */
height: number
/** 头像色块 */
avatar: string
isSelf: boolean
/** 他人添加的成员(只读,不显示编辑/删除) */
isFromOther: boolean
}
/** 头像色块池 */
const AVATAR_COLORS = ['#1385FA', '#2AC79F', '#FF8FAB', '#FFB347', '#A78BFA', '#F87171']
/** Mock 成员列表 */
export const mockMembers: MemberItem[] = [
{
id: 'm-001',
name: '陈小飞',
gender: '男',
age: 28,
height: 175,
avatar: AVATAR_COLORS[0],
isSelf: true,
isFromOther: false,
},
{
id: 'm-002',
name: '李镇南',
gender: '男',
age: 32,
height: 178,
avatar: AVATAR_COLORS[1],
isSelf: false,
isFromOther: false,
},
{
id: 'm-003',
name: '张颖',
gender: '女',
age: 26,
height: 165,
avatar: AVATAR_COLORS[2],
isSelf: false,
isFromOther: false,
},
{
id: 'm-004',
name: '王建国',
gender: '男',
age: 60,
height: 170,
avatar: AVATAR_COLORS[3],
isSelf: false,
isFromOther: true,
},
]
/**
* 生成下一个可用的头像色块
* @param existingCount 已有成员数量
*/
export function nextAvatarColor(existingCount: number): string {
return AVATAR_COLORS[existingCount % AVATAR_COLORS.length]
}