在这里插入图片描述

每日一句正能量

耐住寂寞,深耕自己,那些看似不起眼的点滴积累,终会垒成你重新登高的阶梯。
“点滴积累”看似微不足道,但加上时间和持续性,就能发生质变。积累每一步都实实在在,最终支撑你走出低谷、重新攀登。

前言

摘要:2026年,AI编程教育进入"智能体陪伴式学习"时代。HarmonyOS 6(API 23)引入的鸿蒙智能体框架(HMAF)将AI能力下沉至系统层,配合悬浮导航与沉浸光感特性,为PC端编程学习带来了"代码即光效、状态即导航"的全新交互范式。本文将实战开发一款面向HarmonyOS PC的"鸿蒙代码导师"应用,展示如何利用HMAF构建"代码解析-错误诊断-知识推荐-项目实战"四层智能体协作架构,通过悬浮导航实现学习状态实时追踪,基于沉浸光感打造"专注度即氛围"的沉浸体验,以及基于多窗口架构构建浮动代码提示、实时诊断面板和知识图谱的协作学习体验。

一、前言:AI编程教育3.0时代的智能体革命

2026年,中国开发者规模突破3000万,但传统编程学习平台面临三大痛点:

  1. 反馈滞后:代码报错后,学员需要手动搜索解决方案,平均解决问题时间15分钟
  2. 知识割裂:语法讲解、实战案例、项目源码分散在不同页面,学习路径不清晰
  3. 专注分散:IDE、文档、视频教程、答疑社区四个窗口来回切换,注意力严重分散

HarmonyOS 6(API 23)的HMAF框架配合**悬浮导航(Float Navigation)沉浸光感(Immersive Light Effects)**特性,为编程学习带来了革命性解决方案:

  • 智能体实时诊断:HMAF构建的"诊断智能体"可实时分析代码错误,自动给出修复建议,响应延迟降至800ms
  • 专注度光效感知:根据学员编码节奏、错误频率、停留时长动态切换环境光色,让学员"看见"自己的专注状态
  • 悬浮学习导航:底部悬浮导航实时显示四大智能体运行状态与学习进度徽章,学员无需切换页面即可掌握全局
  • PC多窗口协作:主代码编辑器 + 浮动代码提示窗口 + 浮动诊断面板 + 浮动知识图谱的四层架构,通过光效联动实现"一眼全局"

本文核心亮点

  • 四层智能体架构:解析智能体(代码语义分析)、诊断智能体(错误检测修复)、推荐智能体(知识路径推荐)、实战智能体(项目实战指导)协同工作
  • 专注度脉搏光效:根据编码节奏(冷启动蓝→平稳绿→深度橙→心流红)动态渲染全屏氛围光
  • 悬浮学习导航:底部悬浮页签承载"代码/诊断/知识/实战"四大模块,实时显示智能体状态徽章与专注度脉冲
  • 错误警示光效:基于代码错误严重程度,触发不同光效警示(警告黄→错误橙→致命红)
  • 多窗口光效同步:主窗口与三个浮动子窗口通过WindowLightSync实现跨窗口光效联动,焦点感知自动调节

二、核心特性解析与技术选型

2.1 HMAF在编程教育场景中的价值

HMAF(Harmony Intelligent Agent Framework)提供四种编排模式,在编程教育场景中各有妙用:

编排模式 编程教育应用场景 技术实现
LLM模式 解析智能体自主生成代码注释与讲解 基于AST自动调用LLM生成语义解释
工作流模式 诊断智能体按预设流程处理代码错误 语法检查→语义分析→修复建议→最佳实践推荐
A2A模式 四大智能体间实时协作与任务分发 诊断智能体发现知识盲区时,推荐智能体同步推送相关课程
OpenClaw模式 学员通过自然语言直接指挥智能体 “帮我解释一下这段ArkTS代码的@State装饰器”

2.2 沉浸光感在编程学习中的创新应用

传统编程学习软件采用固定UI,学员难以感知自己的学习状态。HarmonyOS 6的沉浸光感特性带来三种创新:

专注度脉搏光效:根据编码节奏动态调整背景光色与脉冲频率

  • 冷启动期(<5分钟):深海蓝,缓慢呼吸(4秒/周期)
  • 平稳期(5-30分钟):薄荷绿,平稳律动(2秒/周期)
  • 深度期(30-60分钟):活力橙,快速脉冲(1秒/周期)
  • 心流期(>60分钟):炽烈红,高频闪烁(0.5秒/周期)

错误警示光效:基于代码错误严重程度实时驱动光效

  • 警告级别(Warning):暖黄色光晕从底部升起
  • 错误级别(Error):橙色警示光从边缘收缩
  • 致命级别(Fatal):红色闪烁光全屏覆盖

知识掌握光效:根据学习进度与测试成绩渲染光效强度

  • 掌握度>90%:全屏光效强度100%,配合金色粒子效果
  • 掌握度60-90%:光效强度60%,柔和过渡
  • 掌握度<60%:光效强度30%,提示学员加强练习

2.3 悬浮导航的学习适配

传统编程学习软件采用顶部固定工具栏,占用宝贵竖屏空间。HarmonyOS 6的悬浮导航特性带来:

  • 底部悬浮页签:不遮挡代码编辑器,支持透明度三档调节(55%/70%/85%)
  • 智能体状态徽章:每个页签实时显示对应智能体运行状态(空闲/思考/执行/完成/异常)
  • 专注度实时徽章:导航栏中央显示当前专注时长与代码质量评分,点击展开详细数据
  • 快捷操作入口:长按导航栏唤起快捷菜单,一键切换学习模式/紧急保存/智能体开关

三、项目实战:"鸿蒙代码导师"架构设计

3.1 应用场景与功能规划

面向HarmonyOS PC的编程学习场景,核心功能包括:

功能模块 技术实现 沉浸光感/HMAF应用
主代码编辑器 TextArea + CodeHighlight 专注度脉搏光效背景
悬浮学习导航 HdsTabs + systemMaterialEffect 玻璃拟态页签,智能体状态徽章
解析智能体 HMAF Agent Framework Kit 代码语义解析状态光效反馈
诊断智能体 HMAF + 静态代码分析 错误严重程度光效驱动
推荐智能体 HMAF + 知识图谱 学习路径光效提示
实战智能体 HMAF + 项目模板引擎 项目进度光效反馈
浮动代码提示窗口 子窗口 + List 提示类型色光效同步
浮动诊断面板 子窗口 + HdsNavigation 错误主题色光效同步
浮动知识图谱 子窗口 + Canvas 知识节点色光效

3.2 技术架构图

┌─────────────────────────────────────────────────────────────┐
│                    HarmonyOS 6 PC 主窗口                      │
│  ┌───────────────────────────────────────────────────────┐  │
│  │              沉浸光感层 (AmbientLightLayer)              │  │
│  │         专注度脉搏光效 + 错误警示光效 + 知识掌握光效        │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │           主代码编辑器 (TextArea + CodeHighlight)        │  │
│  │              ArkTS代码 + 语法高亮 + 实时诊断               │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │              悬浮学习导航 (FloatNavigation)              │  │
│  │    代码/诊断/知识/实战 页签 + 智能体状态徽章 + 专注度徽章   │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        ▼                     ▼                     ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│  浮动代码提示   │   │  浮动诊断面板  │   │  浮动知识图谱  │
│  (提示+类型色)  │   │  (错误+严重色) │   │  (节点+掌握色) │
└───────────────┘   └───────────────┘   └───────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        ▼                     ▼                     ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│   解析智能体    │   │   诊断智能体    │   │   推荐智能体    │
│  (AST语义分析)  │   │ (静态分析修复)  │   │ (知识图谱推荐) │
└───────────────┘   └───────────────┘   └───────────────┘
                              │
                              ▼
                    ┌───────────────┐
                    │    实战智能体   │
                    │ (项目模板指导) │
                    └───────────────┘

四、环境配置与模块依赖

4.1 模块依赖配置

entry/oh-package.json5中添加以下依赖:

{
  "dependencies": {
    "@kit.ArkUI": "1.0.0",
    "@kit.WindowManagerKit": "1.0.0",
    "@kit.SensorServiceKit": "1.0.0",
    "@kit.UIDesignKit": "1.0.0",
    "@kit.AgentFrameworkKit": "1.0.0",
    "@kit.IntentsKit": "1.0.0",
    "@kit.CodeAnalysisKit": "1.0.0",
    "@kit.KnowledgeGraphKit": "1.0.0"
  }
}

4.2 权限声明(module.json5)

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET",
        "reason": "$string:internet_permission_reason"
      },
      {
        "name": "ohos.permission.SYSTEM_FLOAT_WINDOW",
        "reason": "$string:float_window_permission_reason"
      },
      {
        "name": "ohos.permission.READ_USER_STORAGE",
        "reason": "$string:storage_permission_reason"
      },
      {
        "name": "ohos.permission.WRITE_USER_STORAGE",
        "reason": "$string:storage_permission_reason"
      }
    ]
  }
}

五、核心组件实战

5.1 窗口沉浸配置(EntryAbility.ets)

// entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.WindowManagerKit';

export default class EntryAbility extends UIAbility {
  async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
    const mainWindow = await windowStage.createSubWindow('code_main');
    
    // 启用全屏沉浸模式,隐藏系统标题栏
    await mainWindow.setWindowLayoutFullScreen(true);
    
    // 设置窗口背景为透明,允许沉浸光效层透传
    await mainWindow.setWindowBackgroundColor('#00000000');
    
    // 加载主页面
    windowStage.loadContent('pages/CodeMentorPage', (err) => {
      if (err) {
        console.error('Failed to load CodeMentorPage:', err.message);
      }
    });

    // 初始化窗口焦点监听,用于光效联动
    mainWindow.on('windowFocusChange', (isFocused: boolean) => {
      AppStorage.setOrCreate('window_focused', isFocused);
    });
  }

  onWindowStageDestroy(): void {
    // 清理窗口资源
  }
}

5.2 专注度脉搏光效系统(FocusLightEffect.ets)

// entry/src/main/ets/components/FocusLightEffect.ets
import { HdsNavigation, SystemMaterialEffect } from '@kit.UIDesignKit';

// 学习阶段枚举
export enum LearningPhase {
  COLD_START = 'cold_start',    // 冷启动 <5分钟
  STEADY = 'steady',            // 平稳期 5-30分钟
  DEEP = 'deep',                // 深度期 30-60分钟
  FLOW = 'flow'                 // 心流期 >60分钟
}

// 错误严重程度枚举
export enum ErrorSeverity {
  WARNING = 'warning',          // 警告
  ERROR = 'error',              // 错误
  FATAL = 'fatal'               // 致命
}

// 智能体状态枚举
export enum AgentState {
  IDLE = 'idle',
  THINKING = 'thinking',
  EXECUTING = 'executing',
  COMPLETED = 'completed',
  ERROR = 'error'
}

@Component
export struct FocusLightEffect {
  @Prop focusDuration: number = 0;      // 专注时长(分钟)
  @Prop errorCount: number = 0;         // 当前错误数
  @Prop codeQuality: number = 0;        // 代码质量评分(0-100)
  @State lightIntensity: number = 0.6;
  @State pulsePhase: number = 0;

  // 学习阶段主题色映射
  private phaseColors: Map<LearningPhase, string> = new Map([
    [LearningPhase.COLD_START, '#1E3A8A'],    // 深海蓝
    [LearningPhase.STEADY, '#10B981'],         // 薄荷绿
    [LearningPhase.DEEP, '#F59E0B'],           // 活力橙
    [LearningPhase.FLOW, '#EF4444']            // 炽烈红
  ]);

  // 错误严重色映射
  private errorColors: Map<ErrorSeverity, string> = new Map([
    [ErrorSeverity.WARNING, '#FCD34D'],   // 暖黄色
    [ErrorSeverity.ERROR, '#F97316'],      // 橙色
    [ErrorSeverity.FATAL, '#EF4444']       // 红色
  ]);

  // 脉冲周期映射(毫秒)
  private pulseDurations: Map<LearningPhase, number> = new Map([
    [LearningPhase.COLD_START, 4000],
    [LearningPhase.STEADY, 2000],
    [LearningPhase.DEEP, 1000],
    [LearningPhase.FLOW, 500]
  ]);

  private getCurrentPhase(): LearningPhase {
    if (this.focusDuration < 5) return LearningPhase.COLD_START;
    if (this.focusDuration < 30) return LearningPhase.STEADY;
    if (this.focusDuration < 60) return LearningPhase.DEEP;
    return LearningPhase.FLOW;
  }

  private getThemeColor(): string {
    // 如果有错误,优先显示错误色
    if (this.errorCount > 0) {
      return this.errorColors.get(ErrorSeverity.ERROR) || '#F97316';
    }
    return this.phaseColors.get(this.getCurrentPhase()) || '#1E3A8A';
  }

  private getPulseDuration(): number {
    return this.pulseDurations.get(this.getCurrentPhase()) || 4000;
  }

  // 代码质量影响光效强度
  private getIntensityByQuality(): number {
    if (this.codeQuality > 90) return 1.0;
    if (this.codeQuality > 60) return 0.6;
    return 0.3;
  }

  aboutToAppear(): void {
    // 启动光效脉冲动画
    this.startPulseAnimation();
  }

  private startPulseAnimation(): void {
    setInterval(() => {
      this.pulsePhase = this.pulsePhase === 0 ? 1 : 0;
    }, this.getPulseDuration() / 2);
  }

  build() {
    Stack() {
      // 底层:专注度脉搏光效(大面积模糊光晕)
      Column()
        .width(800)
        .height(800)
        .backgroundColor(this.getThemeColor())
        .blur(200)
        .opacity(this.getIntensityByQuality() * 0.25)
        .position({ x: '50%', y: '30%' })
        .anchor('50%')
        .scale({
          x: this.pulsePhase === 0 ? 1.0 : 1.3,
          y: this.pulsePhase === 0 ? 1.0 : 1.3
        })
        .animation({
          duration: this.getPulseDuration(),
          curve: Curve.EaseInOut,
          iterations: -1,
          playMode: PlayMode.Alternate
        })

      // 中层:错误警示光效(边缘收缩)
      if (this.errorCount > 0) {
        Column()
          .width('100%')
          .height('100%')
          .backgroundColor('transparent')
          .border({
            width: 4,
            color: this.errorColors.get(ErrorSeverity.ERROR) || '#F97316'
          })
          .opacity(0.3)
          .animation({
            duration: 1000,
            curve: Curve.EaseInOut,
            iterations: -1,
            playMode: PlayMode.Alternate
          })
          .borderWidth(this.pulsePhase === 0 ? 4 : 8)
      }

      // 顶层:代码质量粒子效果(仅在高质量时显示)
      if (this.codeQuality > 80) {
        this.buildParticleEffect()
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#050508')
  }

  @Builder
  buildParticleEffect(): void {
    ForEach([0, 1, 2, 3, 4], (index: number) => {
      Column()
        .width(4)
        .height(4)
        .backgroundColor('#10B981')
        .borderRadius(2)
        .opacity(0.6)
        .position({
          x: `${20 + index * 15}%`,
          y: `${30 + index * 10}%`
        })
        .animation({
          duration: 1500 + index * 300,
          curve: Curve.Linear,
          iterations: -1,
          playMode: PlayMode.Alternate
        })
        .translate({
          y: this.pulsePhase === 0 ? -20 : -100
        })
    })
  }
}

5.3 HMAF四层智能体调度器(CodeAgentScheduler.ets)

// entry/src/main/ets/agents/CodeAgentScheduler.ets
import { hmaf } from '@kit.AgentFrameworkKit';
import { intents } from '@kit.IntentsKit';

// 智能体类型枚举
export enum AgentType {
  PARSER = 'parser',            // 解析智能体
  DIAGNOSTIC = 'diagnostic',    // 诊断智能体
  RECOMMENDER = 'recommender',  // 推荐智能体
  PRACTICE = 'practice'         // 实战智能体
}

// 智能体人格色彩映射
export enum AgentPersonality {
  PARSER = '#8B5CF6',       // 智慧紫
  DIAGNOSTIC = '#EF4444',    // 诊断红
  RECOMMENDER = '#06B6D4',   // 推荐青
  PRACTICE = '#F59E0B'       // 实战橙
}

export class CodeAgentScheduler {
  private static instance: CodeAgentScheduler;
  private hmafSession: hmaf.AgentSession | null = null;
  private intentEngine: intents.IntentEngine | null = null;
  
  // 智能体状态管理
  private agentStates: Map<string, AgentState> = new Map([
    ['parser-1', AgentState.IDLE],
    ['diagnostic-1', AgentState.IDLE],
    ['recommender-1', AgentState.IDLE],
    ['practice-1', AgentState.IDLE]
  ]);

  private constructor() {}

  static getInstance(): CodeAgentScheduler {
    if (!CodeAgentScheduler.instance) {
      CodeAgentScheduler.instance = new CodeAgentScheduler();
    }
    return CodeAgentScheduler.instance;
  }

  async initialize(): Promise<void> {
    // 初始化HMAF多智能体会话
    this.hmafSession = await hmaf.createAgentSession({
      mode: hmaf.AgentMode.MULTI_AGENT,
      enableDistributed: true,
      maxConcurrentAgents: 4
    });

    // 初始化意图引擎
    this.intentEngine = await intents.createIntentEngine({
      supportedDomains: ['code_analysis', 'error_diagnosis', 'knowledge_recommendation', 'project_guidance']
    });

    // 注册四大智能体
    await this.registerAgents();

    // 启动状态监听
    this.startStateMonitoring();
  }

  private async registerAgents(): Promise<void> {
    // 1. 解析智能体:基于AST进行代码语义分析
    await this.hmafSession?.registerAgent({
      agentId: 'parser-1',
      agentType: AgentType.PARSER,
      capabilities: ['ast_analysis', 'semantic_extraction', 'code_annotation', 'architecture_explanation'],
      modelConfig: {
        modelType: 'llm',
        temperature: 0.3,
        maxTokens: 1024
      }
    });

    // 2. 诊断智能体:静态代码分析与错误修复
    await this.hmafSession?.registerAgent({
      agentId: 'diagnostic-1',
      agentType: AgentType.DIAGNOSTIC,
      capabilities: ['syntax_check', 'type_inference', 'error_localization', 'fix_suggestion', 'best_practice_check'],
      modelConfig: {
        modelType: 'llm',
        temperature: 0.1,
        maxTokens: 512
      }
    });

    // 3. 推荐智能体:基于知识图谱的学习路径推荐
    await this.hmafSession?.registerAgent({
      agentId: 'recommender-1',
      agentType: AgentType.RECOMMENDER,
      capabilities: ['knowledge_gap_analysis', 'learning_path_generation', 'resource_recommendation', 'difficulty_assessment'],
      modelConfig: {
        modelType: 'llm',
        temperature: 0.5,
        maxTokens: 512
      }
    });

    // 4. 实战智能体:项目模板与实战指导
    await this.hmafSession?.registerAgent({
      agentId: 'practice-1',
      agentType: AgentType.PRACTICE,
      capabilities: ['project_template_generation', 'step_by_step_guidance', 'code_review', 'performance_optimization'],
      modelConfig: {
        modelType: 'llm',
        temperature: 0.4,
        maxTokens: 1024
      }
    });
  }

  // 解析代码语义
  async parseCode(code: string, language: string): Promise<{ ast: object; explanation: string; annotations: string[] }> {
    this.updateAgentState('parser-1', AgentState.THINKING);
    
    const result = await this.hmafSession?.sendTask({
      targetAgent: 'parser-1',
      taskType: 'parse_code',
      payload: {
        code: code,
        language: language,  // 'arkts', 'typescript', 'javascript'
        includeAst: true,
        includeExplanation: true
      }
    });

    this.updateAgentState('parser-1', AgentState.COMPLETED);
    return {
      ast: result?.ast || {},
      explanation: result?.explanation || '',
      annotations: result?.annotations || []
    };
  }

  // 诊断代码错误
  async diagnoseCode(code: string, filePath: string): Promise<{ errors: CodeError[]; fixes: CodeFix[]; quality: number }> {
    this.updateAgentState('diagnostic-1', AgentState.EXECUTING);
    
    const result = await this.hmafSession?.sendTask({
      targetAgent: 'diagnostic-1',
      taskType: 'diagnose_code',
      payload: {
        code: code,
        filePath: filePath,
        framework: 'arkui',
        apiLevel: 23
      }
    });

    this.updateAgentState('diagnostic-1', AgentState.COMPLETED);
    
    return {
      errors: result?.errors || [],
      fixes: result?.fixes || [],
      quality: result?.qualityScore || 0
    };
  }

  // 推荐学习路径
  async recommendLearningPath(userId: string, currentTopic: string): Promise<{ path: LearningNode[]; resources: Resource[] }> {
    this.updateAgentState('recommender-1', AgentState.THINKING);
    
    const result = await this.hmafSession?.sendTask({
      targetAgent: 'recommender-1',
      taskType: 'generate_learning_path',
      payload: {
        userId: userId,
        currentTopic: currentTopic,
        targetLevel: 'advanced',
        preferredStyle: 'project_based'
      }
    });

    this.updateAgentState('recommender-1', AgentState.COMPLETED);
    
    return {
      path: result?.learningPath || [],
      resources: result?.resources || []
    };
  }

  // 生成实战项目
  async generatePracticeProject(difficulty: string, topic: string): Promise<{ template: string; steps: string[]; hints: string[] }> {
    this.updateAgentState('practice-1', AgentState.THINKING);
    
    const result = await this.hmafSession?.sendTask({
      targetAgent: 'practice-1',
      taskType: 'generate_project',
      payload: {
        difficulty: difficulty,  // 'beginner', 'intermediate', 'advanced'
        topic: topic,
        framework: 'arkui',
        includeTests: true
      }
    });

    this.updateAgentState('practice-1', AgentState.COMPLETED);
    
    return {
      template: result?.projectTemplate || '',
      steps: result?.steps || [],
      hints: result?.hints || []
    };
  }

  private updateAgentState(agentId: string, state: AgentState): void {
    this.agentStates.set(agentId, state);
    AppStorage.setOrCreate('agent_state_update', { agentId, state });
  }

  getAgentState(agentId: string): AgentState {
    return this.agentStates.get(agentId) || AgentState.IDLE;
  }

  private startStateMonitoring(): void {
    // 监听智能体状态变化,同步到UI
    this.hmafSession?.on('agentStateChange', (event: { agentId: string; state: string }) => {
      this.updateAgentState(event.agentId, event.state as AgentState);
    });
  }
}

// 代码错误类型
export interface CodeError {
  line: number;
  column: number;
  severity: 'warning' | 'error' | 'fatal';
  message: string;
  code: string;
}

// 代码修复建议
export interface CodeFix {
  title: string;
  description: string;
  replacement: string;
  line: number;
}

// 学习节点
export interface LearningNode {
  id: string;
  title: string;
  description: string;
  difficulty: number;
  estimatedTime: number;
  prerequisites: string[];
}

// 学习资源
export interface Resource {
  id: string;
  title: string;
  type: 'article' | 'video' | 'project' | 'quiz';
  url: string;
  difficulty: number;
}

5.4 悬浮学习导航(CodeFloatNavigation.ets)

// entry/src/main/ets/components/CodeFloatNavigation.ets
import { window } from '@kit.ArkUI';
import { AgentState, AgentType, AgentPersonality } from '../agents/CodeAgentScheduler';
import { LearningPhase } from './FocusLightEffect';

interface NavItem {
  id: string;
  icon: Resource;
  label: string;
  page: string;
  agentType?: AgentType;
}

@Component
export struct CodeFloatNavigation {
  @State currentIndex: number = 0;
  @State navTransparency: number = 0.70;
  @State isExpanded: boolean = false;
  @State bottomAvoidHeight: number = 0;
  @State focusDuration: number = 0;
  @State codeQuality: number = 0;
  @State currentPhase: LearningPhase = LearningPhase.COLD_START;
  @State agentStates: Map<string, AgentState> = new Map([
    ['parser-1', AgentState.IDLE],
    ['diagnostic-1', AgentState.IDLE],
    ['recommender-1', AgentState.IDLE],
    ['practice-1', AgentState.IDLE]
  ]);

  private navItems: NavItem[] = [
    { id: 'code', icon: $r('app.media.ic_code'), label: '代码', page: 'CodePage' },
    { id: 'diagnostic', icon: $r('app.media.ic_bug'), label: '诊断', page: 'DiagnosticPage', agentType: AgentType.DIAGNOSTIC },
    { id: 'knowledge', icon: $r('app.media.ic_book'), label: '知识', page: 'KnowledgePage', agentType: AgentType.RECOMMENDER },
    { id: 'practice', icon: $r('app.media.ic_project'), label: '实战', page: 'PracticePage', agentType: AgentType.PRACTICE },
    { id: 'settings', icon: $r('app.media.ic_settings'), label: '设置', page: 'SettingsPage' }
  ];

  aboutToAppear(): void {
    this.getBottomAvoidArea();

    // 监听智能体状态更新
    AppStorage.watch('agent_state_update', (update: { agentId: string; state: string }) => {
      this.agentStates.set(update.agentId, update.state as AgentState);
    });

    // 监听学习数据
    AppStorage.watch('learning_metrics', (metrics: { focusDuration: number; codeQuality: number }) => {
      this.focusDuration = metrics.focusDuration;
      this.codeQuality = metrics.codeQuality;
      this.updateLearningPhase();
    });
  }

  private updateLearningPhase(): void {
    if (this.focusDuration < 5) this.currentPhase = LearningPhase.COLD_START;
    else if (this.focusDuration < 30) this.currentPhase = LearningPhase.STEADY;
    else if (this.focusDuration < 60) this.currentPhase = LearningPhase.DEEP;
    else this.currentPhase = LearningPhase.FLOW;
  }

  private async getBottomAvoidArea(): Promise<void> {
    try {
      const mainWindow = await window.getLastWindow();
      const avoidArea = mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
      this.bottomAvoidHeight = avoidArea.bottomRect.height;
    } catch (error) {
      console.error('Failed to get avoid area:', error);
    }
  }

  private getAgentStateForNavItem(item: NavItem): AgentState {
    if (!item.agentType) return AgentState.IDLE;
    
    const agentIdMap: Record<string, string> = {
      [AgentType.PARSER]: 'parser-1',
      [AgentType.DIAGNOSTIC]: 'diagnostic-1',
      [AgentType.RECOMMENDER]: 'recommender-1',
      [AgentType.PRACTICE]: 'practice-1'
    };
    
    return this.agentStates.get(agentIdMap[item.agentType]) || AgentState.IDLE;
  }

  private getPhaseColor(): string {
    const colors: Record<LearningPhase, string> = {
      [LearningPhase.COLD_START]: '#1E3A8A',
      [LearningPhase.STEADY]: '#10B981',
      [LearningPhase.DEEP]: '#F59E0B',
      [LearningPhase.FLOW]: '#EF4444'
    };
    return colors[this.currentPhase];
  }

  private getStateBadgeColor(state: AgentState): string {
    const colors: Record<AgentState, string> = {
      [AgentState.IDLE]: '#888888',
      [AgentState.THINKING]: '#8B5CF6',
      [AgentState.EXECUTING]: '#F97316',
      [AgentState.COMPLETED]: '#10B981',
      [AgentState.ERROR]: '#EF4444'
    };
    return colors[state] || '#888888';
  }

  private getStateBadgeAnimation(state: AgentState): object {
    switch (state) {
      case AgentState.THINKING:
        return {
          duration: 1500,
          curve: Curve.EaseInOut,
          iterations: -1,
          playMode: PlayMode.Alternate
        };
      case AgentState.EXECUTING:
        return {
          duration: 800,
          curve: Curve.Linear,
          iterations: -1
        };
      case AgentState.ERROR:
        return {
          duration: 400,
          curve: Curve.EaseInOut,
          iterations: -1,
          playMode: PlayMode.Alternate
        };
      default:
        return { duration: 0 };
    }
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      Column() {
        this.contentBuilder()
      }
      .padding({ bottom: this.bottomAvoidHeight + 90 })

      // 悬浮导航容器
      Column() {
        Stack() {
          // 玻璃拟态背景层
          Column()
            .width('100%')
            .height('100%')
            .backgroundBlurStyle(BlurStyle.REGULAR)
            .opacity(this.navTransparency)
            .backdropFilter($r('sys.blur.20'))

          // 渐变叠加层
          Column()
            .width('100%')
            .height('100%')
            .linearGradient({
              direction: GradientDirection.Top,
              colors: [
                ['rgba(255,255,255,0.15)', 0.0],
                ['rgba(255,255,255,0.05)', 1.0]
              ]
            })
        }
        .width('100%')
        .height('100%')
        .borderRadius(28)
        .shadow({
          radius: 24,
          color: 'rgba(0,0,0,0.25)',
          offsetX: 0,
          offsetY: -6
        })

        Column() {
          // 学习信息栏(展开时显示)
          if (this.isExpanded) {
            Row() {
              Column() {
                Text(`${this.focusDuration}分钟`)
                  .fontSize(13)
                  .fontColor('#FFFFFF')
                  .fontWeight(FontWeight.Bold)
                
                Text('专注时长')
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.6)')
              }
              .layoutWeight(1)

              Column() {
                Text(`${this.codeQuality}`)
                  .fontSize(13)
                  .fontColor(this.getQualityColor())
                  .fontWeight(FontWeight.Bold)
                
                Text('代码质量')
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.6)')
              }
              .layoutWeight(1)

              Column() {
                Text(this.getPhaseLabel())
                  .fontSize(13)
                  .fontColor(this.getPhaseColor())
                  .fontWeight(FontWeight.Bold)
                
                Text('学习阶段')
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.6)')
              }
              .layoutWeight(1)
            }
            .width('100%')
            .height(50)
            .padding({ left: 16, right: 16 })
            .backgroundColor('rgba(0,0,0,0.2)')
            .borderRadius({ topLeft: 28, topRight: 28 })
          }

          // 导航页签
          Row() {
            ForEach(this.navItems, (item: NavItem, index: number) => {
              Column() {
                Stack() {
                  Image(item.icon)
                    .width(26)
                    .height(26)
                    .fillColor(this.currentIndex === index ? this.getPhaseColor() : '#AAAAAA')

                  // 智能体状态徽章
                  if (item.agentType && this.getAgentStateForNavItem(item) !== AgentState.IDLE) {
                    Column()
                      .width(10)
                      .height(10)
                      .backgroundColor(this.getStateBadgeColor(this.getAgentStateForNavItem(item)))
                      .borderRadius(5)
                      .position({ x: 20, y: -4 })
                      .shadow({
                        radius: 8,
                        color: this.getStateBadgeColor(this.getAgentStateForNavItem(item)),
                        offsetX: 0,
                        offsetY: 0
                      })
                      .animation(this.getStateBadgeAnimation(this.getAgentStateForNavItem(item)))
                  }
                }
                .width(44)
                .height(44)

                Text(item.label)
                  .fontSize(11)
                  .fontColor(this.currentIndex === index ? this.getPhaseColor() : '#BBBBBB')
                  .margin({ top: 4 })
              }
              .layoutWeight(1)
              .onClick(() => {
                this.currentIndex = index;
                this.triggerHapticFeedback();
                AppStorage.setOrCreate('nav_page_change', item.page);
              })
            })
          }
          .width('100%')
          .height(this.isExpanded ? 70 : 80)
          .padding({ left: 16, right: 16 })
          .justifyContent(FlexAlign.SpaceAround)

          // 透明度调节(展开时显示)
          if (this.isExpanded) {
            Row() {
              Text('透明度')
                .fontSize(12)
                .fontColor('rgba(255,255,255,0.7)')
                .margin({ right: 8 })

              Slider({
                value: this.navTransparency * 100,
                min: 55,
                max: 85,
                step: 15,
                style: SliderStyle.InSet
              })
                .width(120)
                .onChange((value: number) => {
                  this.navTransparency = value / 100;
                })

              Text(`${Math.round(this.navTransparency * 100)}%`)
                .fontSize(12)
                .fontColor('rgba(255,255,255,0.7)')
                .margin({ left: 8 })
            }
            .width('100%')
            .height(40)
            .justifyContent(FlexAlign.Center)
          }
        }
        .width('100%')
        .height('100%')
      }
      .width('92%')
      .height(this.isExpanded ? 160 : 80)
      .margin({ bottom: this.bottomAvoidHeight + 12, left: '4%', right: '4%' })
      .animation({
        duration: 350,
        curve: Curve.Spring,
        iterations: 1
      })
      .gesture(
        LongPressGesture({ duration: 600 })
          .onAction(() => {
            this.isExpanded = !this.isExpanded;
          })
      )
    }
    .width('100%')
    .height('100%')
  }

  private getPhaseLabel(): string {
    const labels: Record<LearningPhase, string> = {
      [LearningPhase.COLD_START]: '冷启动',
      [LearningPhase.STEADY]: '平稳期',
      [LearningPhase.DEEP]: '深度期',
      [LearningPhase.FLOW]: '心流期'
    };
    return labels[this.currentPhase];
  }

  private getQualityColor(): string {
    if (this.codeQuality >= 90) return '#10B981';
    if (this.codeQuality >= 60) return '#F59E0B';
    return '#EF4444';
  }

  @BuilderParam contentBuilder: () => void = this.defaultContentBuilder;

  @Builder
  defaultContentBuilder(): void {
    Column() {
      Text('代码编辑区域')
        .fontSize(16)
        .fontColor('#999999')
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }

  private triggerHapticFeedback(): void {
    try {
      import('@kit.SensorServiceKit').then(sensor => {
        sensor.vibrator.startVibration({
          type: 'time',
          duration: 40
        }, { id: 0 });
      });
    } catch (error) {
      console.error('Haptic feedback failed:', error);
    }
  }
}

5.5 代码诊断面板(DiagnosticPanel.ets)

// entry/src/main/ets/components/DiagnosticPanel.ets
import { CodeAgentScheduler, CodeError, CodeFix } from '../agents/CodeAgentScheduler';
import { ErrorSeverity } from './FocusLightEffect';

@Component
export struct DiagnosticPanel {
  @State errorList: CodeError[] = [];
  @State fixList: CodeFix[] = [];
  @State codeQuality: number = 0;
  @State autoFixEnabled: boolean = true;
  @State severityFilter: ErrorSeverity | 'all' = 'all';
  private scheduler: CodeAgentScheduler = CodeAgentScheduler.getInstance();

  aboutToAppear(): void {
    // 监听代码变化,实时诊断
    AppStorage.watch('code_content', async (code: string) => {
      if (code && code.length > 10) {
        await this.runDiagnostics(code);
      }
    });
  }

  private async runDiagnostics(code: string): Promise<void> {
    const result = await this.scheduler.diagnoseCode(code, 'src/pages/Index.ets');
    
    this.errorList = result.errors;
    this.fixList = result.fixes;
    this.codeQuality = result.quality;

    // 同步到全局状态
    AppStorage.setOrCreate('learning_metrics', {
      focusDuration: AppStorage.get('focus_duration') || 0,
      codeQuality: this.codeQuality
    });

    // 同步错误光效
    const hasFatal = this.errorList.some(e => e.severity === 'fatal');
    const hasError = this.errorList.some(e => e.severity === 'error');
    
    if (hasFatal) {
      AppStorage.setOrCreate('current_error_severity', ErrorSeverity.FATAL);
    } else if (hasError) {
      AppStorage.setOrCreate('current_error_severity', ErrorSeverity.ERROR);
    } else if (this.errorList.length > 0) {
      AppStorage.setOrCreate('current_error_severity', ErrorSeverity.WARNING);
    } else {
      AppStorage.setOrCreate('current_error_severity', null);
    }
  }

  private getSeverityColor(severity: string): string {
    const colors: Record<string, string> = {
      'warning': '#FCD34D',
      'error': '#F97316',
      'fatal': '#EF4444'
    };
    return colors[severity] || '#888888';
  }

  private getSeverityIcon(severity: string): string {
    const icons: Record<string, string> = {
      'warning': '⚠️',
      'error': '❌',
      'fatal': '🔴'
    };
    return icons[severity] || '💬';
  }

  build() {
    Column() {
      // 面板标题栏
      Row() {
        Text('🔍 代码诊断')
          .fontSize(16)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Bold)
        
        Row({ space: 8 }) {
          Toggle({ type: ToggleType.Switch, isOn: this.autoFixEnabled })
            .selectedColor('#10B981')
            .onChange((isOn: boolean) => {
              this.autoFixEnabled = isOn;
            })
          
          Text('自动修复')
            .fontSize(12)
            .fontColor('rgba(255,255,255,0.7)')
        }
      }
      .width('100%')
      .height(50)
      .padding({ left: 16, right: 16 })
      .justifyContent(FlexAlign.SpaceBetween)

      // 质量评分环
      Stack() {
        Circle()
          .width(100)
          .height(100)
          .fill('transparent')
          .stroke('rgba(255,255,255,0.1)')
          .strokeWidth(10)

        Circle()
          .width(100)
          .height(100)
          .fill('transparent')
          .stroke(this.getQualityColor())
          .strokeWidth(10)
          .strokeDashArray([this.codeQuality * 2.8, 280])
          .strokeLineCap(LineCapStyle.Round)
          .animation({
            duration: 1000,
            curve: Curve.EaseInOut
          })

        Text(`${this.codeQuality}`)
          .fontSize(24)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
      .height(140)
      .margin({ top: 16, bottom: 16 })

      // 严重程度过滤标签
      Row({ space: 8 }) {
        this.buildFilterChip('全部', 'all');
        this.buildFilterChip('警告', ErrorSeverity.WARNING);
        this.buildFilterChip('错误', ErrorSeverity.ERROR);
        this.buildFilterChip('致命', ErrorSeverity.FATAL);
      }
      .width('100%')
      .height(40)
      .padding({ left: 16, right: 16 })

      // 错误列表
      List() {
        ForEach(this.getFilteredErrors(), (error: CodeError) => {
          ListItem() {
            Column() {
              Row() {
                Text(`${this.getSeverityIcon(error.severity)}${error.line}`)
                  .fontSize(12)
                  .fontColor(this.getSeverityColor(error.severity))
                  .fontWeight(FontWeight.Medium)

                Text(error.code)
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.4)')
                  .backgroundColor('rgba(255,255,255,0.1)')
                  .padding({ left: 6, right: 6, top: 2, bottom: 2 })
                  .borderRadius(4)
              }
              .width('100%')
              .justifyContent(FlexAlign.SpaceBetween)

              Text(error.message)
                .fontSize(13)
                .fontColor('#FFFFFF')
                .margin({ top: 4, bottom: 4 })
                .maxLines(2)
                .textOverflow({ overflow: TextOverflow.Ellipsis })

              // 修复建议
              const fix = this.fixList.find(f => f.line === error.line);
              if (fix && this.autoFixEnabled) {
                Row() {
                  Text(`💡 ${fix.title}`)
                    .fontSize(11)
                    .fontColor('#10B981')
                    .maxLines(1)
                    .textOverflow({ overflow: TextOverflow.Ellipsis })
                  
                  Text('应用修复')
                    .fontSize(11)
                    .fontColor('#FFFFFF')
                    .backgroundColor('#10B981')
                    .padding({ left: 8, right: 8, top: 4, bottom: 4 })
                    .borderRadius(8)
                    .onClick(() => {
                      AppStorage.setOrCreate('apply_fix', fix);
                    })
                }
                .width('100%')
                .padding(8)
                .backgroundColor('rgba(16, 185, 129, 0.1)')
                .borderRadius(8)
                .margin({ top: 4 })
                .justifyContent(FlexAlign.SpaceBetween)
              }
            }
            .width('100%')
            .padding(12)
            .backgroundColor('rgba(255,255,255,0.05)')
            .borderRadius(12)
            .margin({ bottom: 8 })
          }
        })
      }
      .width('100%')
      .layoutWeight(1)
      .padding({ left: 12, right: 12 })
      .edgeEffect(EdgeEffect.Spring)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('rgba(10, 10, 15, 0.95)')
    .borderRadius(16)
  }

  @Builder
  buildFilterChip(label: string, value: ErrorSeverity | 'all'): void {
    const isSelected = this.severityFilter === value;
    
    Text(label)
      .fontSize(11)
      .fontColor(isSelected ? '#FFFFFF' : 'rgba(255,255,255,0.6)')
      .backgroundColor(isSelected ? 'rgba(255,255,255,0.2)' : 'transparent')
      .padding({ left: 12, right: 12, top: 6, bottom: 6 })
      .borderRadius(16)
      .onClick(() => {
        this.severityFilter = value;
      })
  }

  private getFilteredErrors(): CodeError[] {
    if (this.severityFilter === 'all') return this.errorList;
    return this.errorList.filter(item => item.severity === this.severityFilter);
  }

  private getQualityColor(): string {
    if (this.codeQuality >= 90) return '#10B981';
    if (this.codeQuality >= 60) return '#F59E0B';
    return '#EF4444';
  }
}

5.6 浮动知识图谱窗口(KnowledgeGraphWindow.ets)

// entry/src/main/ets/windows/KnowledgeGraphWindow.ets
import { window } from '@kit.WindowManagerKit';
import { CodeAgentScheduler, LearningNode, Resource } from '../agents/CodeAgentScheduler';

@Component
export struct KnowledgeGraphWindow {
  @State learningPath: LearningNode[] = [];
  @State resources: Resource[] = [];
  @State currentTopic: string = 'ArkTS基础';
  @State masteryLevel: number = 0;
  private scheduler: CodeAgentScheduler = CodeAgentScheduler.getInstance();

  aboutToAppear(): void {
    this.loadLearningPath();
  }

  private async loadLearningPath(): Promise<void> {
    const result = await this.scheduler.recommendLearningPath('user_001', this.currentTopic);
    this.learningPath = result.path;
    this.resources = result.resources;
    
    // 计算掌握度
    const completed = this.learningPath.filter(n => n.difficulty <= this.masteryLevel).length;
    this.masteryLevel = Math.round((completed / this.learningPath.length) * 100);
  }

  private getNodeColor(difficulty: number): string {
    if (difficulty <= 2) return '#10B981';  // 初级-绿
    if (difficulty <= 4) return '#F59E0B';  // 中级-橙
    return '#EF4444';                        // 高级-红
  }

  private getNodeStatusColor(node: LearningNode): string {
    if (this.masteryLevel >= node.difficulty * 20) return '#10B981';
    if (this.masteryLevel >= node.difficulty * 10) return '#F59E0B';
    return 'rgba(255,255,255,0.3)';
  }

  build() {
    Column() {
      // 标题栏
      Row() {
        Text('🧠 知识图谱')
          .fontSize(16)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Bold)
        
        Text(`掌握度: ${this.masteryLevel}%`)
          .fontSize(12)
          .fontColor(this.getMasteryColor())
          .backgroundColor(`${this.getMasteryColor()}20`)
          .padding({ left: 10, right: 10, top: 4, bottom: 4 })
          .borderRadius(12)
      }
      .width('100%')
      .height(50)
      .padding({ left: 16, right: 16 })
      .justifyContent(FlexAlign.SpaceBetween)

      // 学习路径可视化
      List() {
        ForEach(this.learningPath, (node: LearningNode, index: number) => {
          ListItem() {
            Row() {
              // 节点状态指示器
              Stack() {
                Circle()
                  .width(40)
                  .height(40)
                  .fill(this.getNodeStatusColor(node))
                  .shadow({
                    radius: 10,
                    color: this.getNodeStatusColor(node),
                    offsetX: 0,
                    offsetY: 0
                  })

                Text(`${index + 1}`)
                  .fontSize(14)
                  .fontColor('#FFFFFF')
                  .fontWeight(FontWeight.Bold)
              }

              Column() {
                Text(node.title)
                  .fontSize(14)
                  .fontColor('#FFFFFF')
                  .fontWeight(FontWeight.Medium)

                Text(node.description)
                  .fontSize(11)
                  .fontColor('rgba(255,255,255,0.5)')
                  .margin({ top: 4 })
                  .maxLines(2)
                  .textOverflow({ overflow: TextOverflow.Ellipsis })

                Row({ space: 8 }) {
                  Text(`难度: ${'⭐'.repeat(node.difficulty)}`)
                    .fontSize(10)
                    .fontColor(this.getNodeColor(node.difficulty))

                  Text(`${node.estimatedTime}分钟`)
                    .fontSize(10)
                    .fontColor('rgba(255,255,255,0.4)')
                }
                .margin({ top: 6 })
              }
              .layoutWeight(1)
              .margin({ left: 12 })

              // 学习按钮
              Button('学习')
                .fontSize(11)
                .fontColor('#FFFFFF')
                .backgroundColor(this.getNodeStatusColor(node) === '#10B981' ? '#10B981' : '#8B5CF6')
                .padding({ left: 12, right: 12, top: 6, bottom: 6 })
                .borderRadius(12)
                .onClick(() => {
                  AppStorage.setOrCreate('start_learning', node);
                })
            }
            .width('100%')
            .padding(12)
            .backgroundColor('rgba(255,255,255,0.05)')
            .borderRadius(12)
          }
          .margin({ bottom: 8 })
        })
      }
      .width('100%')
      .layoutWeight(1)
      .padding({ left: 12, right: 12 })

      // 推荐资源
      Column() {
        Text('📚 推荐资源')
          .fontSize(14)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Medium)
          .margin({ bottom: 8 })

        List() {
          ForEach(this.resources.slice(0, 3), (resource: Resource) => {
            ListItem() {
              Row() {
                Text(this.getResourceIcon(resource.type))
                  .fontSize(20)
                  .margin({ right: 8 })

                Column() {
                  Text(resource.title)
                    .fontSize(12)
                    .fontColor('#FFFFFF')
                    .maxLines(1)
                    .textOverflow({ overflow: TextOverflow.Ellipsis })

                  Text(`${resource.type} · 难度${resource.difficulty}`)
                    .fontSize(10)
                    .fontColor('rgba(255,255,255,0.5)')
                }
                .layoutWeight(1)

                Image($r('app.media.ic_external_link'))
                  .width(16)
                  .height(16)
                  .fillColor('rgba(255,255,255,0.5)')
              }
              .width('100%')
              .padding(8)
              .backgroundColor('rgba(255,255,255,0.03)')
              .borderRadius(8)
            }
            .onClick(() => {
              // 打开资源链接
            })
          })
        }
        .width('100%')
        .height(120)
      }
      .width('100%')
      .padding(16)
      .backgroundColor('rgba(255,255,255,0.05)')
      .borderRadius(12)
      .margin({ left: 12, right: 12, top: 12 })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('rgba(10, 10, 15, 0.95)')
    .borderRadius(16)
  }

  private getMasteryColor(): string {
    if (this.masteryLevel >= 80) return '#10B981';
    if (this.masteryLevel >= 50) return '#F59E0B';
    return '#EF4444';
  }

  private getResourceIcon(type: string): string {
    const icons: Record<string, string> = {
      'article': '📄',
      'video': '🎬',
      'project': '🔧',
      'quiz': '📝'
    };
    return icons[type] || '📎';
  }
}

5.7 多窗口光效同步管理器(WindowLightSync.ets)

// entry/src/main/ets/utils/WindowLightSync.ets
import { window } from '@kit.WindowManagerKit';

export class WindowLightSync {
  private static instance: WindowLightSync;
  private subWindows: Map<string, window.Window> = new Map();
  private currentTheme: string = '#1E3A8A';
  private currentIntensity: number = 0.6;

  private constructor() {}

  static getInstance(): WindowLightSync {
    if (!WindowLightSync.instance) {
      WindowLightSync.instance = new WindowLightSync();
    }
    return WindowLightSync.instance;
  }

  async registerSubWindow(name: string, win: window.Window): Promise<void> {
    this.subWindows.set(name, win);
    await this.syncLightToWindow(win);
  }

  async syncGlobalLightEffect(themeColor: string, intensity?: number): Promise<void> {
    this.currentTheme = themeColor;
    if (intensity !== undefined) {
      this.currentIntensity = intensity;
    }

    for (const [name, win] of this.subWindows) {
      await this.syncLightToWindow(win);
    }

    AppStorage.setOrCreate('global_theme_color', this.currentTheme);
    AppStorage.setOrCreate('global_light_intensity', this.currentIntensity);
  }

  private async syncLightToWindow(win: window.Window): Promise<void> {
    try {
      await win.setWindowBackgroundColor(`${this.currentTheme}20`);
      await win.setWindowShadow({
        radius: 20,
        color: `${this.currentTheme}40`,
        offsetX: 0,
        offsetY: 4
      });
    } catch (error) {
      console.error(`Failed to sync light to window:`, error);
    }
  }

  async handleFocusChange(focusedWindowName: string): Promise<void> {
    for (const [name, win] of this.subWindows) {
      const isFocused = name === focusedWindowName;
      const intensity = isFocused ? this.currentIntensity : this.currentIntensity * 0.4;
      
      try {
        await win.setWindowBackgroundColor(`${this.currentTheme}${Math.floor(intensity * 255).toString(16).padStart(2, '0')}`);
      } catch (error) {
        console.error(`Failed to handle focus change:`, error);
      }
    }
  }

  async createCodeHintWindow(): Promise<window.Window> {
    const hintWindow = await window.createWindow({
      name: 'code_hint_float',
      windowType: window.WindowType.TYPE_FLOAT,
      ctx: getContext()
    });

    await hintWindow.moveWindowTo(1200, 100);
    await hintWindow.resize(320, 500);
    await hintWindow.setWindowLayoutFullScreen(true);
    await hintWindow.setWindowBackgroundColor('#00000000');

    this.registerSubWindow('code_hint', hintWindow);
    return hintWindow;
  }

  async createDiagnosticWindow(): Promise<window.Window> {
    const diagnosticWindow = await window.createWindow({
      name: 'diagnostic_float',
      windowType: window.WindowType.TYPE_FLOAT,
      ctx: getContext()
    });

    await diagnosticWindow.moveWindowTo(50, 100);
    await diagnosticWindow.resize(300, 520);
    await diagnosticWindow.setWindowLayoutFullScreen(true);
    await diagnosticWindow.setWindowBackgroundColor('#00000000');

    this.registerSubWindow('diagnostic', diagnosticWindow);
    return diagnosticWindow;
  }

  async createKnowledgeWindow(): Promise<window.Window> {
    const knowledgeWindow = await window.createWindow({
      name: 'knowledge_float',
      windowType: window.WindowType.TYPE_FLOAT,
      ctx: getContext()
    });

    await knowledgeWindow.moveWindowTo(50, 650);
    await knowledgeWindow.resize(300, 280);
    await knowledgeWindow.setWindowLayoutFullScreen(true);
    await knowledgeWindow.setWindowBackgroundColor('#00000000');

    this.registerSubWindow('knowledge', knowledgeWindow);
    return knowledgeWindow;
  }
}

5.8 主页面集成(CodeMentorPage.ets)

// entry/src/main/ets/pages/CodeMentorPage.ets
import { FocusLightEffect, LearningPhase, ErrorSeverity } from '../components/FocusLightEffect';
import { CodeFloatNavigation } from '../components/CodeFloatNavigation';
import { DiagnosticPanel } from '../components/DiagnosticPanel';
import { KnowledgeGraphWindow } from '../windows/KnowledgeGraphWindow';
import { WindowLightSync } from '../utils/WindowLightSync';
import { CodeAgentScheduler } from '../agents/CodeAgentScheduler';

@Entry
@Component
struct CodeMentorPage {
  @State currentPage: string = 'CodePage';
  @State focusDuration: number = 0;
  @State codeQuality: number = 85;
  @State currentErrorSeverity: ErrorSeverity | null = null;
  @State codeContent: string = '';
  @State isLearningStarted: boolean = false;
  private windowSync: WindowLightSync = WindowLightSync.getInstance();
  private scheduler: CodeAgentScheduler = CodeAgentScheduler.getInstance();
  private focusTimer: number = 0;

  aboutToAppear(): async () => {
    await this.scheduler.initialize();
    await this.initializeWindows();
    this.startFocusTracking();
    this.startMetricsSimulation();

    AppStorage.watch('nav_page_change', (page: string) => {
      this.currentPage = page;
    });
  }

  private async initializeWindows(): Promise<void> {
    await this.windowSync.createCodeHintWindow();
    await this.windowSync.createDiagnosticWindow();
    await this.windowSync.createKnowledgeWindow();
  }

  private startFocusTracking(): void {
    // 每60秒增加专注时长
    this.focusTimer = setInterval(() => {
      if (this.isLearningStarted) {
        this.focusDuration++;
        AppStorage.setOrCreate('focus_duration', this.focusDuration);
        AppStorage.setOrCreate('learning_metrics', {
          focusDuration: this.focusDuration,
          codeQuality: this.codeQuality
        });

        const phase = this.getCurrentPhase();
        const themeColor = this.getPhaseColor(phase);
        this.windowSync.syncGlobalLightEffect(themeColor, this.getIntensityByQuality());
      }
    }, 60000);
  }

  private startMetricsSimulation(): void {
    setInterval(() => {
      // 模拟代码质量波动
      const fluctuation = Math.floor(Math.random() * 10) - 3;
      this.codeQuality = Math.max(30, Math.min(100, this.codeQuality + fluctuation));

      AppStorage.setOrCreate('learning_metrics', {
        focusDuration: this.focusDuration,
        codeQuality: this.codeQuality
      });
    }, 10000);
  }

  private getCurrentPhase(): LearningPhase {
    if (this.focusDuration < 5) return LearningPhase.COLD_START;
    if (this.focusDuration < 30) return LearningPhase.STEADY;
    if (this.focusDuration < 60) return LearningPhase.DEEP;
    return LearningPhase.FLOW;
  }

  private getPhaseColor(phase: LearningPhase): string {
    const colors: Record<LearningPhase, string> = {
      [LearningPhase.COLD_START]: '#1E3A8A',
      [LearningPhase.STEADY]: '#10B981',
      [LearningPhase.DEEP]: '#F59E0B',
      [LearningPhase.FLOW]: '#EF4444'
    };
    return colors[phase];
  }

  private getIntensityByQuality(): number {
    if (this.codeQuality > 90) return 1.0;
    if (this.codeQuality > 60) return 0.6;
    return 0.3;
  }

  build() {
    Stack() {
      // 底层:沉浸光效层
      FocusLightEffect({
        focusDuration: this.focusDuration,
        errorCount: this.currentErrorSeverity ? 1 : 0,
        codeQuality: this.codeQuality
      })

      // 中层:主内容区域
      Column() {
        this.buildHeader()
        
        Stack() {
          if (this.currentPage === 'CodePage') {
            this.buildCodePage()
          } else if (this.currentPage === 'DiagnosticPage') {
            DiagnosticPanel()
          } else if (this.currentPage === 'KnowledgePage') {
            KnowledgeGraphWindow()
          } else if (this.currentPage === 'PracticePage') {
            this.buildPracticePage()
          }
        }
        .layoutWeight(1)
      }
      .width('100%')
      .height('100%')

      // 顶层:悬浮导航
      CodeFloatNavigation({
        contentBuilder: () => {}
      })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#050508')
    .expandSafeArea(
      [SafeAreaType.SYSTEM],
      [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM, SafeAreaEdge.START, SafeAreaEdge.END]
    )
  }

  @Builder
  buildHeader(): void {
    Row() {
      Column() {
        Text('💻 鸿蒙代码导师')
          .fontSize(20)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Bold)
        
        Text(`专注时长: ${this.focusDuration}分钟 | 代码质量: ${this.codeQuality}`)
          .fontSize(12)
          .fontColor('rgba(255,255,255,0.6)')
          .margin({ top: 4 })
      }
      .alignItems(HorizontalAlign.Start)

      Row({ space: 12 }) {
        Button(this.isLearningStarted ? '暂停学习' : '开始学习')
          .fontSize(13)
          .fontColor('#FFFFFF')
          .backgroundColor(this.isLearningStarted ? '#F59E0B' : '#10B981')
          .padding({ left: 20, right: 20, top: 8, bottom: 8 })
          .borderRadius(20)
          .onClick(() => {
            this.isLearningStarted = !this.isLearningStarted;
            if (this.isLearningStarted) {
              // 启动解析智能体
              this.scheduler.parseCode(this.codeContent, 'arkts');
            }
          })

        Button('智能体面板')
          .fontSize(13)
          .fontColor('#FFFFFF')
          .backgroundColor('rgba(255,255,255,0.1)')
          .padding({ left: 16, right: 16, top: 8, bottom: 8 })
          .borderRadius(20)
          .onClick(() => {
            AppStorage.setOrCreate('show_agent_panel', true);
          })
      }
    }
    .width('100%')
    .height(70)
    .padding({ left: 24, right: 24 })
    .backgroundBlurStyle(BlurStyle.REGULAR)
    .backdropFilter($r('sys.blur.20'))
    .border({
      width: { bottom: 1 },
      color: 'rgba(255,255,255,0.1)'
    })
    .justifyContent(FlexAlign.SpaceBetween)
  }

  @Builder
  buildCodePage(): void {
    Column() {
      // 代码编辑器
      Stack() {
        TextArea({ text: $$this.codeContent })
          .width('90%')
          .height(400)
          .backgroundColor('rgba(255,255,255,0.05)')
          .borderRadius(16)
          .fontColor('#FFFFFF')
          .fontSize(14)
          .placeholder('在此输入ArkTS代码...')
          .placeholderColor('rgba(255,255,255,0.3)')
          .onChange((value: string) => {
            this.codeContent = value;
            AppStorage.setOrCreate('code_content', value);
          })

        if (!this.isLearningStarted) {
          Column() {
            Text('📝')
              .fontSize(48)
              .margin({ bottom: 16 })
            
            Text('点击"开始学习"启动AI智能体编程导师')
              .fontSize(14)
              .fontColor('rgba(255,255,255,0.6)')
          }
        }
      }
      .width('100%')
      .height(420)
      .margin({ top: 20, bottom: 20 })

      // 快捷代码片段
      Row({ space: 12 }) {
        this.buildCodeSnippet('@State', '#8B5CF6');
        this.buildCodeSnippet('@Builder', '#06B6D4');
        this.buildCodeSnippet('@Entry', '#10B981');
        this.buildCodeSnippet('Row()', '#F59E0B');
        this.buildCodeSnippet('Column()', '#EF4444');
      }
      .margin({ bottom: 20 })
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  buildCodeSnippet(label: string, color: string): void {
    Text(label)
      .fontSize(12)
      .fontColor(color)
      .backgroundColor(`${color}20`)
      .padding({ left: 12, right: 12, top: 8, bottom: 8 })
      .borderRadius(12)
      .border({ width: 1, color: `${color}40` })
      .onClick(() => {
        this.codeContent += `\n${label}`;
        AppStorage.setOrCreate('code_content', this.codeContent);
      })
  }

  @Builder
  buildPracticePage(): void {
    Column() {
      Text('🚀 实战项目')
        .fontSize(18)
        .fontColor('#FFFFFF')
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 20 })

      List() {
        ForEach([
          { title: '待办清单应用', difficulty: 1, time: 30 },
          { title: '天气查询组件', difficulty: 2, time: 45 },
          { title: '音乐播放器', difficulty: 3, time: 60 },
          { title: '电商商品页', difficulty: 4, time: 90 },
          { title: '社交聊天应用', difficulty: 5, time: 120 }
        ], (project: { title: string; difficulty: number; time: number }) => {
          ListItem() {
            Row() {
              Column() {
                Text(project.title)
                  .fontSize(14)
                  .fontColor('#FFFFFF')
                
                Text(`难度: ${'⭐'.repeat(project.difficulty)} · ${project.time}分钟`)
                  .fontSize(11)
                  .fontColor('rgba(255,255,255,0.5)')
                  .margin({ top: 4 })
              }
              .alignItems(HorizontalAlign.Start)
              .layoutWeight(1)

              Button('开始')
                .fontSize(12)
                .fontColor('#FFFFFF')
                .backgroundColor('#8B5CF6')
                .padding({ left: 16, right: 16, top: 6, bottom: 6 })
                .borderRadius(12)
                .onClick(() => {
                  this.scheduler.generatePracticeProject(
                    project.difficulty <= 2 ? 'beginner' : project.difficulty <= 4 ? 'intermediate' : 'advanced',
                    project.title
                  );
                })
            }
            .width('100%')
            .padding(16)
            .backgroundColor('rgba(255,255,255,0.05)')
            .borderRadius(12)
          }
          .margin({ bottom: 12 })
        })
      }
      .width('90%')
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
  }
}

六、关键技术总结

6.1 HMAF编程教育智能体开发清单

技术点 API/方法 应用场景
智能体会话创建 hmaf.createAgentSession({ mode: MULTI_AGENT }) 四层智能体协同教学
意图解析 intents.createIntentEngine({ supportedDomains }) 学员问题意图识别
任务分发 hmafSession.sendTask({ targetAgent, taskType }) 智能体间教学任务调度
状态监听 AppStorage 全局状态回调 跨组件学习状态同步
分布式协同 enableDistributed: true 多设备学习协作
LLM代码解析 modelType: 'llm' 解析智能体生成代码注释
静态分析 modelType: 'classification' 诊断智能体检测代码错误
知识图谱 modelType: 'llm' 推荐智能体生成学习路径

6.2 沉浸光感实现清单

技术点 API/方法 应用场景
系统材质效果 systemMaterialEffect: SystemMaterialEffect.IMMERSIVE 标题栏沉浸效果
背景模糊 backgroundBlurStyle(BlurStyle.REGULAR) 悬浮导航玻璃拟态
背景滤镜 backdropFilter($r('sys.blur.20')) 精细模糊控制
安全区扩展 expandSafeArea([SafeAreaType.SYSTEM], [...]) 全屏沉浸布局
窗口沉浸 setWindowLayoutFullScreen(true) 无边框模式
光效动画 animation({ duration, iterations: -1 }) 专注度脉搏呼吸灯
动态透明度 backgroundOpacity 焦点感知降级
窗口阴影 setWindowShadow({ radius, color }) 跨窗口光效联动

6.3 学习状态光效映射

学习阶段 专注时长 主题色 脉冲周期 光效强度
冷启动 <5分钟 深海蓝 #1E3A8A 4秒 30%
平稳期 5-30分钟 薄荷绿 #10B981 2秒 60%
深度期 30-60分钟 活力橙 #F59E0B 1秒 80%
心流期 >60分钟 炽烈红 #EF4444 0.5秒 100%

6.4 智能体状态徽章动画

智能体状态 徽章颜色 动画效果 教学含义
空闲 #888888 静态 智能体待命
思考中 #8B5CF6 呼吸脉冲 LLM分析代码中
执行中 #F97316 旋转进度 诊断/推荐处理中
已完成 #10B981 静态 任务执行成功
异常 #EF4444 快速闪烁 诊断发现严重错误

6.5 性能优化建议

  1. 光效渲染优化:使用willChange: true标记频繁变化的动画层,避免全量重绘
  2. 智能体并发控制:通过maxConcurrentAgents: 4限制并发,防止资源争抢
  3. 代码编辑器虚拟化:当代码超过1000行时,使用虚拟滚动
  4. 窗口管理:子窗口使用TYPE_FLOAT类型,避免创建过多独立进程
  5. 诊断节流:代码诊断频率控制在5秒/次,避免频繁分析

七、总结与展望

本文基于HarmonyOS 6(API 23)的HMAF智能体框架、悬浮导航与沉浸光感特性,构建了一套面向PC端编程学习的"鸿蒙代码导师"系统。核心创新点包括:

  1. 四层智能体协作架构:解析、诊断、推荐、实战四大智能体通过HMAF的A2A模式实时协作,将学员从重复性搜索中解放出来
  2. 专注度脉搏光效系统:基于实时专注时长与代码质量的动态光效渲染,让学员"看见"自己的学习状态
  3. 悬浮学习导航:底部玻璃拟态导航承载四大模块,智能体状态徽章实时反馈,学习信息一键展开
  4. 多窗口光效联动:主窗口与三个浮动子窗口通过WindowLightSync实现跨窗口光效同步,焦点感知自动调节
  5. 错误警示光效:基于代码错误严重程度,触发不同光效警示,帮助学员快速定位问题

随着HarmonyOS生态的持续发展,编程教育智能体将向着"数字人导师"“多模态交互”"跨设备学习协作"等方向演进。HMAF框架的分布式能力与HarmonyOS的跨端协同特性,将为编程教育带来"一机学全局、多屏协同练"的全新体验。


转载自:https://blog.csdn.net/u014727709/article/details/161227792
欢迎 👍点赞✍评论⭐收藏,欢迎指正

Logo

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

更多推荐