代码功能概述

这段代码实现了一个智能睡眠质量分析器应用,专注于监测、分析和改善用户的睡眠质量。主要功能包括:

  • 睡眠记录追踪:记录每日睡眠时间、入睡时间和醒来时间

  • 睡眠质量评估:基于多个维度自动评估睡眠质量

  • 睡眠周期分析:分析深睡、浅睡和REM睡眠分布

  • 睡眠环境监测:记录卧室温度、光照和噪音水平

  • 智能建议系统:根据睡眠数据提供个性化改善建议

  • 睡眠趋势分析:展示睡眠质量的长期变化趋势

  • 就寝提醒:设置个性化的就寝和起床提醒

  • 健康报告生成:生成周度和月度睡眠健康报告

通过这个示例,可以深入理解ArkTS如何实现复杂的数据分析和健康监测功能。

2. 代码逻辑分析

应用采用"多维度睡眠评估"的架构设计:

  1. 数据采集模块

    • 手动输入睡眠数据 → 自动计算睡眠时长 → 记录环境因素

    • 模拟传感器数据 → 实时更新睡眠状态 → 保存睡眠记录

  2. 质量评估引擎

    • 分析睡眠时长 → 评估入睡时间 → 计算睡眠效率

    • 综合环境因素 → 生成质量评分 → 确定改进方向

  3. 智能建议算法

    • 识别睡眠问题 → 匹配改善策略 → 生成个性化建议

    • 考虑用户习惯 → 避免重复建议 → 跟踪建议效果

  4. 可视化分析系统

    • 聚合历史数据 → 计算睡眠趋势 → 生成可视化图表

    • 比较不同周期 → 识别模式变化 → 预测睡眠质量

  5. 提醒优化机制

    • 分析睡眠规律 → 优化就寝时间 → 自动调整提醒

    • 考虑作息差异 → 适应生活变化 → 提供灵活选择

完整代码

@Entry
@Component
struct SleepQualityAnalyzer {
  @State sleepRecords: SleepRecord[] = [];
  @State currentSleep: SleepSession = new SleepSession();
  @State sleepGoals: SleepGoals = new SleepGoals();
  @State sleepStats: SleepStatistics = new SleepStatistics();
  @State activeView: string = 'dashboard';
  @State environmentData: EnvironmentData = new EnvironmentData();
  @State sleepTips: SleepTip[] = [];

  aboutToAppear() {
    this.loadSampleData();
    this.updateSleepStats();
  }

  build() {
    Column({ space: 0 }) {
      this.BuildAppHeader()
      
      if (this.activeView === 'dashboard') {
        this.BuildDashboard()
      } else if (this.activeView === 'analysis') {
        this.BuildDetailedAnalysis()
      } else if (this.activeView === 'trends') {
        this.BuildTrendsView()
      } else if (this.activeView === 'settings') {
        this.BuildSettingsView()
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0F1B2D')
  }

  @Builder BuildAppHeader() {
    Column({ space: 0 }) {
      Row({ space: 10 }) {
        Text('🌙 睡眠分析器')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
        
        Button('📊')
          .onClick(() => { this.activeView = 'dashboard'; })
          .backgroundColor(this.activeView === 'dashboard' ? '#3A506B' : 'transparent')
          .fontColor('#FFFFFF')
          .borderRadius(20)
          .width(40)
          .height(40)
        
        Button('🔍')
          .onClick(() => { this.activeView = 'analysis'; })
          .backgroundColor(this.activeView === 'analysis' ? '#3A506B' : 'transparent')
          .fontColor('#FFFFFF')
          .borderRadius(20)
          .width(40)
          .height(40)
        
        Button('📈')
          .onClick(() => { this.activeView = 'trends'; })
          .backgroundColor(this.activeView === 'trends' ? '#3A506B' : 'transparent')
          .fontColor('#FFFFFF')
          .borderRadius(20)
          .width(40)
          .height(40)
        
        Button('⚙️')
          .onClick(() => { this.activeView = 'settings'; })
          .backgroundColor(this.activeView === 'settings' ? '#3A506B' : 'transparent')
          .fontColor('#FFFFFF')
          .borderRadius(20)
          .width(40)
          .height(40)
      }
      .width('100%')
      .padding(15)
      .backgroundColor('#1C2541')
    }
  }

  @Builder BuildDashboard() {
    Scroll() {
      Column({ space: 25 }) {
        this.BuildCurrentSleepStatus()
        this.BuildQualityScore()
        this.BuildQuickLog()
        this.BuildEnvironmentMonitor()
        this.BuildDailyTip()
      }
      .width('100%')
      .padding(20)
    }
    .width('100%')
    .layoutWeight(1)
  }

  @Builder BuildCurrentSleepStatus() {
    Column({ space: 15 }) {
      Row({ space: 10 }) {
        Text(this.currentSleep.isSleeping ? '🛌 睡眠中' : '🌅 清醒中')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
        
        if (!this.currentSleep.isSleeping) {
          Button('开始睡眠')
            .onClick(() => { this.startSleepTracking(); })
            .backgroundColor('#5BC0BE')
            .fontColor('#0F1B2D')
            .fontSize(12)
            .borderRadius(8)
            .padding({ left: 15, right: 15 })
            .height(36)
        } else {
          Button('结束睡眠')
            .onClick(() => { this.stopSleepTracking(); })
            .backgroundColor('#FF6B6B')
            .fontColor('#FFFFFF')
            .fontSize(12)
            .borderRadius(8)
            .padding({ left: 15, right: 15 })
            .height(36)
        }
      }
      .width('100%')
      
      if (this.currentSleep.isSleeping) {
        Row({ space: 15 }) {
          Column({ space: 5 }) {
            Text('持续时间')
              .fontSize(12)
              .fontColor('#8A9BB2')
            
            Text(`${this.currentSleep.duration}分钟`)
              .fontSize(16)
              .fontWeight(FontWeight.Medium)
              .fontColor('#FFFFFF')
          }
          .layoutWeight(1)
          
          Column({ space: 5 }) {
            Text('睡眠阶段')
              .fontSize(12)
              .fontColor('#8A9BB2')
            
            Text(this.getSleepPhaseName(this.currentSleep.currentPhase))
              .fontSize(16)
              .fontWeight(FontWeight.Medium)
              .fontColor('#FFFFFF')
          }
          .layoutWeight(1)
        }
        .width('100%')
        .padding(15)
        .backgroundColor('#1C2541')
        .borderRadius(12)
      }
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildQualityScore() {
    const latestRecord = this.getLatestRecord();
    const score = latestRecord ? latestRecord.sleepQuality : 0;
    
    Column({ space: 15 }) {
      Row({ space: 10 }) {
        Text('睡眠质量')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
        
        Text(`${score}/100`)
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor(this.getQualityColor(score))
      }
      .width('100%')
      
      // 质量评分环
      Stack() {
        Circle({ width: 160, height: 160 })
          .fill('#1C2541')
          .strokeWidth(10)
          .stroke('#2D3A5D')
        
        Circle({ width: 160, height: 160 })
          .fill(Color.Transparent)
          .strokeWidth(10)
          .stroke(this.getQualityColor(score))
          .strokeDashArray([Math.PI * 80])
          .strokeDashOffset(Math.PI * 80 * (1 - score / 100))
          .strokeLineCap(LineCapStyle.Round)
        
        Column({ space: 5 }) {
          Text(score.toString())
            .fontSize(32)
            .fontWeight(FontWeight.Bold)
            .fontColor('#FFFFFF')
          
          Text('分数')
            .fontSize(14)
            .fontColor('#8A9BB2')
        }
      }
      .width(160)
      .height(160)
      .margin({ top: 10, bottom: 10 })
      
      Row({ space: 15 }) {
        this.BuildQualityIndicator('时长', this.evaluateDuration(latestRecord))
        this.BuildQualityIndicator('深度', this.evaluateDeepSleep(latestRecord))
        this.BuildQualityIndicator('连续', this.evaluateContinuity(latestRecord))
      }
      .width('100%')
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildQualityIndicator(label: string, level: number) {
    const color = level === 2 ? '#5BC0BE' : level === 1 ? '#FFD166' : '#FF6B6B';
    const icon = level === 2 ? '✓' : level === 1 ? '~' : '✗';
    
    Column({ space: 8 }) {
      Text(icon)
        .fontSize(20)
        .fontColor(color)
      
      Text(label)
        .fontSize(12)
        .fontColor('#8A9BB2')
    }
    .layoutWeight(1)
    .padding(12)
    .backgroundColor('#2D3A5D')
    .borderRadius(10)
  }

  @Builder BuildQuickLog() {
    Column({ space: 15 }) {
      Text('快速记录')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      Row({ space: 15 }) {
        Button('😴 记录入睡')
          .onClick(() => { this.logSleepTime('bedtime'); })
          .backgroundColor('#3A506B')
          .fontColor('#FFFFFF')
          .borderRadius(10)
          .layoutWeight(1)
          .height(60)
        
        Button('🌅 记录醒来')
          .onClick(() => { this.logWakeTime(); })
          .backgroundColor('#5BC0BE')
          .fontColor('#0F1B2D')
          .borderRadius(10)
          .layoutWeight(1)
          .height(60)
      }
      .width('100%')
      
      Row({ space: 15 }) {
        Button('💤 记录午睡')
          .onClick(() => { this.logNap(); })
          .backgroundColor('#3A506B')
          .fontColor('#FFFFFF')
          .borderRadius(10)
          .layoutWeight(1)
          .height(60)
        
        Button('📝 添加笔记')
          .onClick(() => { this.showNoteDialog(); })
          .backgroundColor('#3A506B')
          .fontColor('#FFFFFF')
          .borderRadius(10)
          .layoutWeight(1)
          .height(60)
      }
      .width('100%')
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildEnvironmentMonitor() {
    Column({ space: 15 }) {
      Row({ space: 10 }) {
        Text('🌡️')
          .fontSize(18)
        
        Text('睡眠环境')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
      }
      .width('100%')
      
      Row({ space: 15 }) {
        this.BuildEnvironmentMetric('温度', `${this.environmentData.temperature}°C`, 
          this.environmentData.temperature >= 18 && this.environmentData.temperature <= 22)
        this.BuildEnvironmentMetric('光照', `${this.environmentData.lightLevel}lx`, 
          this.environmentData.lightLevel < 20)
      }
      .width('100%')
      
      Row({ space: 15 }) {
        this.BuildEnvironmentMetric('噪音', `${this.environmentData.noiseLevel}dB`, 
          this.environmentData.noiseLevel < 40)
        this.BuildEnvironmentMetric('湿度', `${this.environmentData.humidity}%`, 
          this.environmentData.humidity >= 40 && this.environmentData.humidity <= 60)
      }
      .width('100%')
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildEnvironmentMetric(name: string, value: string, optimal: boolean) {
    Column({ space: 8 }) {
      Text(value)
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .fontColor(optimal ? '#5BC0BE' : '#FF6B6B')
      
      Text(name)
        .fontSize(12)
        .fontColor('#8A9BB2')
    }
    .layoutWeight(1)
    .padding(15)
    .backgroundColor('#2D3A5D')
    .borderRadius(12)
  }

  @Builder BuildDailyTip() {
    const tip = this.getDailyTip();
    
    Column({ space: 15 }) {
      Row({ space: 10 }) {
        Text('💡')
          .fontSize(18)
        
        Text('今日建议')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
      }
      .width('100%')
      
      Text(tip.content)
        .fontSize(14)
        .fontColor('#FFFFFF')
        .lineHeight(20)
      
      if (tip.action) {
        Button(tip.action)
          .onClick(() => { this.applyTipAction(tip); })
          .backgroundColor('#5BC0BE')
          .fontColor('#0F1B2D')
          .width('100%')
          .height(40)
          .margin({ top: 10 })
          .borderRadius(8)
      }
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildDetailedAnalysis() {
    const latestRecord = this.getLatestRecord();
    const analysis = this.analyzeSleepPattern(latestRecord);
    
    Column({ space: 25 }) {
      Text('睡眠深度分析')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .margin({ top: 20 })
      
      this.BuildSleepCycleChart(latestRecord)
      
      this.BuildQualityAssessment(analysis)
      
      this.BuildInfluencingFactors()
      
      this.BuildImprovementSuggestions(analysis)
    }
    .width('100%')
    .padding(20)
  }

  @Builder BuildSleepCycleChart(record: SleepRecord | undefined) {
    Column({ space: 15 }) {
      Text('睡眠周期分布')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      if (record) {
        const total = record.deepSleep + record.lightSleep + record.remSleep;
        const deepPercent = total > 0 ? (record.deepSleep / total) * 100 : 0;
        const lightPercent = total > 0 ? (record.lightSleep / total) * 100 : 0;
        const remPercent = total > 0 ? (record.remSleep / total) * 100 : 0;
        
        Row({ space: 0 }) {
          Rect()
            .width(`${deepPercent}%`)
            .height(40)
            .fill('#5BC0BE')
          
          Rect()
            .width(`${lightPercent}%`)
            .height(40)
            .fill('#3A506B')
          
          Rect()
            .width(`${remPercent}%`)
            .height(40)
            .fill('#FFD166')
        }
        .width('100%')
        .height(40)
        .borderRadius(8)
        .clip(true)
        
        Row({ space: 20 }) {
          this.BuildCycleLegend('深睡', `${record.deepSleep}小时`, '#5BC0BE')
          this.BuildCycleLegend('浅睡', `${record.lightSleep}小时`, '#3A506B')
          this.BuildCycleLegend('REM', `${record.remSleep}小时`, '#FFD166')
        }
        .width('100%')
        .margin({ top: 15 })
      } else {
        Text('暂无详细睡眠数据')
          .fontSize(14)
          .fontColor('#8A9BB2')
          .padding(30)
          .backgroundColor('#1C2541')
          .borderRadius(12)
          .width('100%')
      }
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildCycleLegend(label: string, value: string, color: string) {
    Row({ space: 8 }) {
      Circle()
        .width(12)
        .height(12)
        .fill(color)
      
      Column({ space: 2 }) {
        Text(label)
          .fontSize(12)
          .fontColor('#FFFFFF')
        
        Text(value)
          .fontSize(10)
          .fontColor('#8A9BB2')
      }
    }
    .layoutWeight(1)
  }

  @Builder BuildQualityAssessment(analysis: SleepAnalysis) {
    Column({ space: 15 }) {
      Text('质量评估')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      ForEach(analysis.factors, (factor: QualityFactor) => {
        Row({ space: 10 }) {
          Text(factor.name)
            .fontSize(14)
            .fontColor('#FFFFFF')
            .layoutWeight(1)
          
          Row({ space: 5 }) {
            ForEach([1, 2, 3, 4, 5], (star: number) => {
              Text(star <= factor.rating ? '★' : '☆')
                .fontSize(16)
                .fontColor(star <= factor.rating ? '#FFD166' : '#3A506B')
            })
          }
        }
        .width('100%')
        .padding(12)
        .backgroundColor('#2D3A5D')
        .borderRadius(8)
        .margin({ bottom: 8 })
      })
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildInfluencingFactors() {
    Column({ space: 15 }) {
      Text('影响因素')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      Row({ space: 15 }) {
        this.BuildFactorCard('咖啡因', '下午摄入可能影响', '⚠️')
        this.BuildFactorCard('屏幕时间', '睡前1小时使用', '📱')
      }
      .width('100%')
      
      Row({ space: 15 }) {
        this.BuildFactorCard('压力水平', '中等偏高', '😰')
        this.BuildFactorCard('运动', '睡前3小时运动', '🏃')
      }
      .width('100%')
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildFactorCard(title: string, description: string, icon: string) {
    Column({ space: 10 }) {
      Text(icon)
        .fontSize(24)
      
      Text(title)
        .fontSize(14)
        .fontWeight(FontWeight.Medium)
        .fontColor('#FFFFFF')
        .textAlign(TextAlign.Center)
      
      Text(description)
        .fontSize(12)
        .fontColor('#8A9BB2')
        .textAlign(TextAlign.Center)
    }
    .layoutWeight(1)
    .padding(15)
    .backgroundColor('#2D3A5D')
    .borderRadius(12)
  }

  @Builder BuildImprovementSuggestions(analysis: SleepAnalysis) {
    Column({ space: 15 }) {
      Text('改善建议')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      ForEach(analysis.suggestions.slice(0, 3), (suggestion: string, index: number) => {
        Row({ space: 10 }) {
          Text('👉')
            .fontSize(14)
          
          Text(suggestion)
            .fontSize(14)
            .fontColor('#FFFFFF')
            .lineHeight(20)
            .layoutWeight(1)
        }
        .width('100%')
        .padding(15)
        .backgroundColor(index % 2 === 0 ? '#2D3A5D' : '#1C2541')
        .borderRadius(10)
      })
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildTrendsView() {
    Column({ space: 25 }) {
      Text('睡眠趋势')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .margin({ top: 20 })
      
      this.BuildWeeklyTrendChart()
      
      this.BuildSleepStats()
      
      this.BuildConsistencyScore()
      
      this.BuildBestPractices()
    }
    .width('100%')
    .padding(20)
  }

  @Builder BuildWeeklyTrendChart() {
    const weekData = this.getWeekData();
    
    Column({ space: 15 }) {
      Text('本周睡眠趋势')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      Row({ space: 5 }) {
        ForEach(weekData, (day: WeekData, index: number) => {
          const height = Math.min(day.hours * 20, 120);
          
          Column({ space: 5 }) {
            Rect()
              .width(30)
              .height(height)
              .fill(day.quality >= 80 ? '#5BC0BE' : 
                    day.quality >= 60 ? '#FFD166' : '#FF6B6B')
              .borderRadius(4)
            
            Text(['一', '二', '三', '四', '五', '六', '日'][index])
              .fontSize(12)
              .fontColor('#8A9BB2')
          }
          .layoutWeight(1)
          .height(140)
          .justifyContent(FlexAlign.End)
        })
      }
      .width('100%')
      .height(140)
      .padding(15)
      .backgroundColor('#1C2541')
      .borderRadius(12)
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildSleepStats() {
    Column({ space: 15 }) {
      Text('睡眠统计')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      Row({ space: 15 }) {
        this.BuildStatItem('平均时长', `${this.sleepStats.avgHours.toFixed(1)}小时`, '🕐')
        this.BuildStatItem('最佳质量', `${this.sleepStats.bestQuality}/100`, '🏆')
      }
      .width('100%')
      
      Row({ space: 15 }) {
        this.BuildStatItem('连续天数', `${this.sleepStats.streakDays}天`, '🔥')
        this.BuildStatItem('深睡比例', `${this.sleepStats.deepSleepPercent}%`, '💤')
      }
      .width('100%')
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  @Builder BuildStatItem(label: string, value: string, icon: string) {
    Column({ space: 10 }) {
      Row({ space: 8 }) {
        Text(icon)
          .fontSize(18)
        
        Text(value)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
      }
      
      Text(label)
        .fontSize(12)
        .fontColor('#8A9BB2')
        .textAlign(TextAlign.Center)
    }
    .layoutWeight(1)
    .padding(15)
    .backgroundColor('#2D3A5D')
    .borderRadius(12)
  }

  @Builder BuildSettingsView() {
    Scroll() {
      Column({ space: 25 }) {
        Text('设置')
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
          .margin({ top: 20 })
        
        this.BuildGoalSettings()
        
        this.BuildReminderSettings()
        
        this.BuildEnvironmentSettings()
        
        this.BuildDataManagement()
      }
      .width('100%')
      .padding(20)
    }
    .width('100%')
    .layoutWeight(1)
  }

  @Builder BuildGoalSettings() {
    Column({ space: 15 }) {
      Text('睡眠目标')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .alignSelf(ItemAlign.Start)
      
      Row({ space: 10 }) {
        Text('目标时长:')
          .fontSize(14)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
        
        TextInput({ text: this.sleepGoals.targetHours.toString() })
          .onChange((value: string) => {
            const hours = parseInt(value) || 8;
            this.sleepGoals.targetHours = Math.max(4, Math.min(12, hours));
          })
          .type(InputType.Number)
          .width(80)
          .textAlign(TextAlign.Center)
          .backgroundColor('#2D3A5D')
          .fontColor('#FFFFFF')
          .borderRadius(8)
          .padding(8)
        
        Text('小时')
          .fontSize(14)
          .fontColor('#8A9BB2')
      }
      .width('100%')
      
      Row({ space: 10 }) {
        Text('目标质量:')
          .fontSize(14)
          .fontColor('#FFFFFF')
          .layoutWeight(1)
        
        Text(`${this.sleepGoals.targetQuality}/100`)
          .fontSize(14)
          .fontColor('#5BC0BE')
        
        Slider({
          value: this.sleepGoals.targetQuality,
          min: 50,
          max: 100,
          step: 5,
          style: SliderStyle.OutSet
        })
          .onChange((value: number) => {
            this.sleepGoals.targetQuality = value;
          })
          .width(150)
          .height(30)
      }
      .width('100%')
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#1C2541')
    .borderRadius(16)
  }

  // 以下是私有方法,因篇幅限制仅展示部分
  private loadSampleData(): void {
    this.sleepRecords = [
      { 
        date: '2024-01-15', 
        bedTime: '23:15', 
        wakeTime: '07:30', 
        totalHours: 8.25, 
        sleepQuality: 85,
        deepSleep: 2.5, 
        lightSleep: 4.0, 
        remSleep: 1.75, 
        interruptions: 1,
        notes: '睡眠质量良好'
      },
      { 
        date: '2024-01-14', 
        bedTime: '00:30', 
        wakeTime: '07:00', 
        totalHours: 6.5, 
        sleepQuality: 65,
        deepSleep: 1.8, 
        lightSleep: 3.5, 
        remSleep: 1.2, 
        interruptions: 3,
        notes: '入睡较晚'
      }
    ];
    
    this.sleepTips = [
      { id: '1', content: '建议今晚提前30分钟就寝', category: 'timing', priority: 1, action: '设置提醒' },
      { id: '2', content: '睡前避免使用电子设备', category: 'habit', priority: 2, action: '开启勿扰模式' }
    ];
    
    this.sleepGoals = {
      targetHours: 8,
      targetQuality: 80,
      bedTimeGoal: '23:00',
      wakeTimeGoal: '07:00'
    };
  }

  private updateSleepStats(): void {
    if (this.sleepRecords.length > 0) {
      const totalHours = this.sleepRecords.reduce((sum, record) => sum + record.totalHours, 0);
      const totalQuality = this.sleepRecords.reduce((sum, record) => sum + record.sleepQuality, 0);
      const totalDeepSleep = this.sleepRecords.reduce((sum, record) => sum + record.deepSleep, 0);
      
      this.sleepStats = {
        avgHours: totalHours / this.sleepRecords.length,
        avgQuality: totalQuality / this.sleepRecords.length,
        bestQuality: Math.max(...this.sleepRecords.map(r => r.sleepQuality)),
        streakDays: this.calculateStreak(),
        deepSleepPercent: totalDeepSleep / totalHours * 100
      };
    }
  }

  private getLatestRecord(): SleepRecord | undefined {
    return this.sleepRecords.length > 0 ? this.sleepRecords[this.sleepRecords.length - 1] : undefined;
  }

  private getDailyTip(): SleepTip {
    return this.sleepTips.length > 0 ? this.sleepTips[0] : {
      id: 'default',
      content: '保持规律的作息时间有助于提高睡眠质量',
      category: 'general',
      priority: 3,
      action: ''
    };
  }

  private getQualityColor(score: number): string {
    if (score >= 80) return '#5BC0BE';
    if (score >= 60) return '#FFD166';
    return '#FF6B6B';
  }

  private getSleepPhaseName(phase: string): string {
    switch(phase) {
      case 'deep': return '深睡期';
      case 'light': return '浅睡期';
      case 'rem': return 'REM期';
      default: return '清醒期';
    }
  }

  private startSleepTracking(): void {
    this.currentSleep.isSleeping = true;
    this.currentSleep.startTime = new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' });
    
    // 模拟睡眠阶段变化
    setInterval(() => {
      if (this.currentSleep.isSleeping) {
        this.currentSleep.duration += 1;
        // 简单模拟睡眠阶段循环
        const phaseIndex = Math.floor(this.currentSleep.duration / 30) % 4;
        this.currentSleep.currentPhase = ['light', 'deep', 'light', 'rem'][phaseIndex];
      }
    }, 1000);
  }

  private stopSleepTracking(): void {
    this.currentSleep.isSleeping = false;
    
    // 创建睡眠记录
    const newRecord: SleepRecord = {
      date: new Date().toISOString().split('T')[0],
      bedTime: this.currentSleep.startTime,
      wakeTime: new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }),
      totalHours: this.currentSleep.duration / 60,
      sleepQuality: this.calculateSleepQuality(),
      deepSleep: this.currentSleep.duration * 0.2 / 60,
      lightSleep: this.currentSleep.duration * 0.5 / 60,
      remSleep: this.currentSleep.duration * 0.3 / 60,
      interruptions: Math.floor(Math.random() * 3),
      notes: ''
    };
    
    this.sleepRecords.push(newRecord);
    this.updateSleepStats();
    this.currentSleep = new SleepSession();
  }

  private calculateSleepQuality(): number {
    // 简化质量计算:基于时长和环境因素
    const durationScore = Math.min(this.currentSleep.duration / 480 * 100, 100); // 8小时为满分
    const envScore = (this.environmentData.temperature >= 18 && this.environmentData.temperature <= 22 ? 25 : 0) +
                     (this.environmentData.lightLevel < 20 ? 25 : 0) +
                     (this.environmentData.noiseLevel < 40 ? 25 : 0) +
                     (this.environmentData.humidity >= 40 && this.environmentData.humidity <= 60 ? 25 : 0);
    
    return Math.floor((durationScore + envScore) / 2);
  }

  private evaluateDuration(record: SleepRecord | undefined): number {
    if (!record) return 0;
    if (record.totalHours >= 7 && record.totalHours <= 9) return 2;
    if (record.totalHours >= 6 && record.totalHours <= 10) return 1;
    return 0;
  }

  private evaluateDeepSleep(record: SleepRecord | undefined): number {
    if (!record) return 0;
    const deepSleepPercent = record.totalHours > 0 ? (record.deepSleep / record.totalHours) * 100 : 0;
    if (deepSleepPercent >= 20) return 2;
    if (deepSleepPercent >= 15) return 1;
    return 0;
  }

  private evaluateContinuity(record: SleepRecord | undefined): number {
    if (!record) return 0;
    if (record.interruptions === 0) return 2;
    if (record.interruptions <= 2) return 1;
    return 0;
  }

  private analyzeSleepPattern(record: SleepRecord | undefined): SleepAnalysis {
    if (!record) {
      return {
        overallScore: 0,
        factors: [],
        suggestions: ['开始记录睡眠以获得个性化分析']
      };
    }
    
    return {
      overallScore: record.sleepQuality,
      factors: [
        { name: '睡眠时长', rating: this.evaluateDuration(record) >= 2 ? 5 : this.evaluateDuration(record) >= 1 ? 3 : 1 },
        { name: '睡眠深度', rating: this.evaluateDeepSleep(record) >= 2 ? 5 : this.evaluateDeepSleep(record) >= 1 ? 3 : 1 },
        { name: '睡眠连续性', rating: this.evaluateContinuity(record) >= 2 ? 5 : this.evaluateContinuity(record) >= 1 ? 3 : 1 },
        { name: '入睡时间', rating: this.evaluateBedTime(record) >= 2 ? 5 : this.evaluateBedTime(record) >= 1 ? 3 : 1 }
      ],
      suggestions: this.generateSuggestions(record)
    };
  }

  private evaluateBedTime(record: SleepRecord): number {
    const bedHour = parseInt(record.bedTime.split(':')[0]);
    if (bedHour >= 22 && bedHour <= 23) return 2;
    if (bedHour >= 21 && bedHour <= 24) return 1;
    return 0;
  }

  private generateSuggestions(record: SleepRecord): string[] {
    const suggestions = [];
    
    if (record.totalHours < 7) {
      suggestions.push('睡眠时长不足,建议增加30-60分钟睡眠时间');
    }
    
    if (record.totalHours > 9) {
      suggestions.push('睡眠时长过长,可能影响日间精力');
    }
    
    const deepSleepPercent = record.totalHours > 0 ? (record.deepSleep / record.totalHours) * 100 : 0;
    if (deepSleepPercent < 15) {
      suggestions.push('深睡比例偏低,建议保持安静黑暗的睡眠环境');
    }
    
    if (record.interruptions > 2) {
      suggestions.push('睡眠中断较多,建议减少夜间饮水和电子设备使用');
    }
    
    return suggestions.length > 0 ? suggestions : ['睡眠质量良好,继续保持!'];
  }

  private getWeekData(): WeekData[] {
    // 返回示例数据
    return [
      { day: '一', hours: 7.5, quality: 82 },
      { day: '二', hours: 6.8, quality: 75 },
      { day: '三', hours: 8.2, quality: 88 },
      { day: '四', hours: 7.0, quality: 70 },
      { day: '五', hours: 9.1, quality: 92 },
      { day: '六', hours: 8.5, quality: 85 },
      { day: '日', hours: 7.8, quality: 80 }
    ];
  }

  private calculateStreak(): number {
    // 简化实现:返回示例数据
    return 5;
  }

  private logSleepTime(type: string): void {
    console.log(`记录${type}: ${new Date().toLocaleTimeString()}`);
  }

  private logWakeTime(): void {
    console.log('记录醒来时间');
  }

  private logNap(): void {
    console.log('记录午睡');
  }

  private showNoteDialog(): void {
    console.log('显示笔记对话框');
  }

  private applyTipAction(tip: SleepTip): void {
    console.log(`应用建议: ${tip.content}`);
  }
}

// 数据模型定义
class SleepRecord {
  date: string = '';
  bedTime: string = '';
  wakeTime: string = '';
  totalHours: number = 0;
  sleepQuality: number = 0;
  deepSleep: number = 0;
  lightSleep: number = 0;
  remSleep: number = 0;
  interruptions: number = 0;
  notes: string = '';
}

class SleepSession {
  isSleeping: boolean = false;
  startTime: string = '';
  currentPhase: string = 'awake';
  duration: number = 0;
  qualityScore: number = 0;
}

class SleepGoals {
  targetHours: number = 8;
  targetQuality: number = 80;
  bedTimeGoal: string = '23:00';
  wakeTimeGoal: string = '07:00';
}

class SleepStatistics {
  avgHours: number = 0;
  avgQuality: number = 0;
  bestQuality: number = 0;
  streakDays: number = 0;
  deepSleepPercent: number = 0;
}

class EnvironmentData {
  temperature: number = 22;
  lightLevel: number = 10;
  noiseLevel: number = 35;
  humidity: number = 50;
  co2Level: number = 500;
}

class SleepTip {
  id: string = '';
  content: string = '';
  category: string = '';
  priority: number = 1;
  action: string = '';
}

class SleepAnalysis {
  overallScore: number = 0;
  factors: QualityFactor[] = [];
  suggestions: string[] = [];
}

class QualityFactor {
  name: string = '';
  rating: number = 0;
}

class WeekData {
  day: string = '';
  hours: number = 0;
  quality: number = 0;
}

想入门鸿蒙开发又怕花冤枉钱?别错过!现在能免费系统学 -- 从 ArkTS 面向对象核心的类和对象、继承多态,到吃透鸿蒙开发关键技能,还能冲刺鸿蒙基础 +高级开发者证书,更惊喜的是考证成功还送好礼!快加入我的鸿蒙班,一起从入门到精通,班级链接:点击免费进入

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐