在这里插入图片描述

每日一句正能量

黑暗不是终点,而是为了让你更敏锐地感知光的方向。
黑暗(困难、未知、痛苦)不是要吞没你,而是因为消除了光的干扰,反而能让最微弱的光源显形。在低谷中不是绝望,而是训练自己的“感知力”——学会在微弱信号中找到出路。

前言

摘要:2026年,直播电商进入"智能体驱动"时代。HarmonyOS 6(API 23)引入的鸿蒙智能体框架(HMAF)将AI能力下沉至系统层,配合悬浮导航与沉浸光感特性,为PC端直播中控台带来了"数据即氛围、状态即导航"的全新交互范式。本文将实战开发一款面向HarmonyOS PC的"直播智脑"应用,展示如何利用HMAF构建"智能讲解-实时互动-数据洞察-风险管控"四层智能体协作架构,通过悬浮导航实现直播状态实时追踪,基于沉浸光感打造"流量即光效"的沉浸体验,以及基于多窗口架构构建浮动弹幕、数据看板和商品橱窗的协作直播体验。

一、前言:直播电商3.0时代的智能体革命

2026年,中国直播电商市场规模已突破8万亿元,但传统直播中控台面临三大痛点:

  1. 信息过载:主播需要同时盯着弹幕、数据、商品、互动四个面板,注意力严重分散
  2. 响应滞后:人工回复弹幕平均延迟15秒,错过最佳转化窗口
  3. 数据盲区:实时数据与历史趋势割裂,无法即时调整直播策略

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

  • 智能体自动应答:HMAF构建的"互动智能体"可实时理解弹幕意图,自动回复常见问题,响应延迟降至500ms
  • 流量光效感知:根据实时在线人数、GMV增速、互动热度动态切换环境光色,让主播"看见"数据变化
  • 悬浮状态导航:底部悬浮导航实时显示四大智能体运行状态,主播无需切换页面即可掌握全局
  • PC多窗口协作:主直播画面 + 浮动弹幕窗口 + 浮动数据看板 + 浮动商品橱窗的四层架构,通过光效联动实现"一眼全局"

本文核心亮点

  • 四层智能体架构:讲解智能体(商品解说)、互动智能体(弹幕应答)、洞察智能体(数据预测)、风控智能体(违规检测)协同工作
  • 流量脉搏光效:根据实时GMV增速(冷启动蓝→平稳绿→爆发橙→峰值红)动态渲染全屏氛围光
  • 悬浮直播导航:底部悬浮页签承载"直播/互动/数据/商品"四大模块,实时显示智能体状态徽章与流量脉冲
  • 弹幕情绪光效:基于NLP实时分析弹幕情感倾向,正面情绪触发暖光脉冲,负面情绪触发冷光警示
  • 多窗口光效同步:主窗口与三个浮动子窗口通过WindowLightSync实现跨窗口光效联动,焦点感知自动调节

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

2.1 HMAF在直播场景中的价值

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

编排模式 直播应用场景 技术实现
LLM模式 智能讲解智能体自主生成商品解说词 基于商品SKU自动调用LLM生成卖点文案
工作流模式 互动智能体按预设流程处理弹幕问答 意图识别→知识库检索→答案生成→敏感词过滤
A2A模式 四大智能体间实时协作与任务分发 讲解智能体触发促销时,洞察智能体同步预测库存
OpenClaw模式 主播通过自然语言直接指挥智能体 “把三号链接的讲解词换成夏季版本”

2.2 沉浸光感在直播中的创新应用

传统直播软件采用固定UI,主播难以感知数据变化。HarmonyOS 6的沉浸光感特性带来三种创新:

流量脉搏光效:根据实时在线人数动态调整背景光色与脉冲频率

  • 冷启动期(<100人):深海蓝,缓慢呼吸(4秒/周期)
  • 成长期(100-1000人):薄荷绿,平稳律动(2秒/周期)
  • 爆发期(1000-10000人):活力橙,快速脉冲(1秒/周期)
  • 峰值期(>10000人):炽烈红,高频闪烁(0.5秒/周期)

弹幕情绪光效:基于NLP情感分析实时驱动光效

  • 正面情绪(>0.6):暖金色光晕从底部升起
  • 负面情绪(<-0.3):冰蓝色警示光从边缘收缩
  • 中性情绪:保持当前主题色

GMV增速光效:根据成交额增速渲染光效强度

  • 增速>50%:全屏光效强度100%,配合金色粒子效果
  • 增速10-50%:光效强度60%,柔和过渡
  • 增速<10%:光效强度30%,提示主播调整策略

2.3 悬浮导航的直播适配

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

  • 底部悬浮页签:不遮挡直播画面,支持透明度三档调节(55%/70%/85%)
  • 智能体状态徽章:每个页签实时显示对应智能体运行状态(空闲/思考/执行/完成/异常)
  • 流量实时徽章:导航栏中央显示当前在线人数与GMV,点击展开详细数据
  • 快捷操作入口:长按导航栏唤起快捷菜单,一键切换讲解模式/紧急下播/智能体开关

三、项目实战:"直播智脑"架构设计

3.1 应用场景与功能规划

面向HarmonyOS PC的电商直播场景,核心功能包括:

功能模块 技术实现 沉浸光感/HMAF应用
主直播画面窗口 Video + XComponent 流量脉搏光效背景
悬浮直播导航 HdsTabs + systemMaterialEffect 玻璃拟态页签,智能体状态徽章
讲解智能体 HMAF Agent Framework Kit 讲解状态光效反馈
互动智能体 HMAF + NLP意图识别 弹幕情绪光效驱动
洞察智能体 HMAF + 时序预测模型 数据预警光效提示
风控智能体 HMAF + 敏感词检测 违规警示红光闪烁
浮动弹幕窗口 子窗口 + List 弹幕情感色光效同步
浮动数据看板 子窗口 + HdsNavigation 数据主题色光效同步
浮动商品橱窗 子窗口 + Grid 商品类别色光效

3.2 技术架构图

┌─────────────────────────────────────────────────────────────┐
│                    HarmonyOS 6 PC 主窗口                      │
│  ┌───────────────────────────────────────────────────────┐  │
│  │              沉浸光感层 (AmbientLightLayer)              │  │
│  │         流量脉搏光效 + 弹幕情绪光效 + GMV增速光效          │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │           主直播画面 (Video + XComponent)               │  │
│  │              摄像头画面 + 商品展示 + 美颜特效              │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │              悬浮直播导航 (FloatNavigation)              │  │
│  │    直播/互动/数据/商品 页签 + 智能体状态徽章 + 流量徽章    │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        ▼                     ▼                     ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│  浮动弹幕窗口   │   │  浮动数据看板  │   │  浮动商品橱窗  │
│  (弹幕+情感色)  │   │  (实时GMV+光效)│   │  (SKU+类别色) │
└───────────────┘   └───────────────┘   └───────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        ▼                     ▼                     ▼
┌───────────────┐   ┌───────────────┐   ┌───────────────┐
│   讲解智能体    │   │   互动智能体    │   │   洞察智能体    │
│  (LLM生成文案)  │   │ (NLP弹幕应答)  │   │ (时序预测库存) │
└───────────────┘   └───────────────┘   └───────────────┘
                              │
                              ▼
                    ┌───────────────┐
                    │    风控智能体   │
                    │ (敏感词+违规检测)│
                    └───────────────┘

四、环境配置与模块依赖

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.MediaKit": "1.0.0",
    "@kit.NNKit": "1.0.0"
  }
}

4.2 权限声明(module.json5)

{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.CAMERA",
        "reason": "$string:camera_permission_reason"
      },
      {
        "name": "ohos.permission.MICROPHONE",
        "reason": "$string:mic_permission_reason"
      },
      {
        "name": "ohos.permission.INTERNET",
        "reason": "$string:internet_permission_reason"
      },
      {
        "name": "ohos.permission.SYSTEM_FLOAT_WINDOW",
        "reason": "$string:float_window_permission_reason"
      },
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC",
        "reason": "$string:distributed_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('live_main');
    
    // 启用全屏沉浸模式,隐藏系统标题栏
    await mainWindow.setWindowLayoutFullScreen(true);
    
    // 设置窗口背景为透明,允许沉浸光效层透传
    await mainWindow.setWindowBackgroundColor('#00000000');
    
    // 加载主页面
    windowStage.loadContent('pages/LiveControlPage', (err) => {
      if (err) {
        console.error('Failed to load LiveControlPage:', err.message);
      }
    });

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

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

5.2 流量脉搏光效系统(TrafficLightEffect.ets)

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

// 直播阶段枚举
export enum LivePhase {
  COLD_START = 'cold_start',    // 冷启动 <100人
  GROWTH = 'growth',            // 成长期 100-1000人
  EXPLOSION = 'explosion',      // 爆发期 1000-10000人
  PEAK = 'peak'                 // 峰值期 >10000人
}

// 弹幕情感枚举
export enum SentimentType {
  POSITIVE = 'positive',        // 正面 >0.6
  NEUTRAL = 'neutral',          // 中性 -0.3~0.6
  NEGATIVE = 'negative'         // 负面 <-0.3
}

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

@Component
export struct TrafficLightEffect {
  @Prop onlineCount: number = 0;
  @Prop gmvSpeed: number = 0;          // GMV增速百分比
  @Prop sentiment: SentimentType = SentimentType.NEUTRAL;
  @State lightIntensity: number = 0.6;
  @State pulsePhase: number = 0;

  // 流量阶段主题色映射
  private phaseColors: Map<LivePhase, string> = new Map([
    [LivePhase.COLD_START, '#1E3A8A'],    // 深海蓝
    [LivePhase.GROWTH, '#10B981'],         // 薄荷绿
    [LivePhase.EXPLOSION, '#F59E0B'],      // 活力橙
    [LivePhase.PEAK, '#EF4444']            // 炽烈红
  ]);

  // 弹幕情感色映射
  private sentimentColors: Map<SentimentType, string> = new Map([
    [SentimentType.POSITIVE, '#FCD34D'],   // 暖金色
    [SentimentType.NEUTRAL, '#6B7280'],    // 中性灰
    [SentimentType.NEGATIVE, '#60A5FA']    // 冰蓝色
  ]);

  // 脉冲周期映射(毫秒)
  private pulseDurations: Map<LivePhase, number> = new Map([
    [LivePhase.COLD_START, 4000],
    [LivePhase.GROWTH, 2000],
    [LivePhase.EXPLOSION, 1000],
    [LivePhase.PEAK, 500]
  ]);

  private getCurrentPhase(): LivePhase {
    if (this.onlineCount < 100) return LivePhase.COLD_START;
    if (this.onlineCount < 1000) return LivePhase.GROWTH;
    if (this.onlineCount < 10000) return LivePhase.EXPLOSION;
    return LivePhase.PEAK;
  }

  private getThemeColor(): string {
    return this.phaseColors.get(this.getCurrentPhase()) || '#1E3A8A';
  }

  private getSentimentColor(): string {
    return this.sentimentColors.get(this.sentiment) || '#6B7280';
  }

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

  // GMV增速影响光效强度
  private getIntensityByGMV(): number {
    if (this.gmvSpeed > 50) return 1.0;
    if (this.gmvSpeed > 10) 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.getIntensityByGMV() * 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
        })

      // 中层:弹幕情感光效(底部渐变)
      Column()
        .width('100%')
        .height(300)
        .backgroundColor(this.getSentimentColor())
        .opacity(this.sentiment === SentimentType.NEUTRAL ? 0.03 : 0.12)
        .blur(100)
        .position({ x: 0, y: '70%' })
        .linearGradient({
          direction: GradientDirection.Top,
          colors: [
            [this.getSentimentColor(), 0.0],
            ['transparent', 1.0]
          ]
        })
        .animation({
          duration: 2000,
          curve: Curve.EaseInOut
        })

      // 顶层:GMV增速粒子效果(仅在爆发期显示)
      if (this.getCurrentPhase() === LivePhase.EXPLOSION || this.getCurrentPhase() === LivePhase.PEAK) {
        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('#FCD34D')
        .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四层智能体调度器(LiveAgentScheduler.ets)

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

// 智能体类型枚举
export enum AgentType {
  PRESENTER = 'presenter',      // 讲解智能体
  INTERACTION = 'interaction',  // 互动智能体
  INSIGHT = 'insight',          // 洞察智能体
  RISK = 'risk'                 // 风控智能体
}

// 智能体人格色彩映射
export enum AgentPersonality {
  PRESENTER = '#8B5CF6',       // 智慧紫
  INTERACTION = '#F97316',      // 活力橙
  INSIGHT = '#06B6D4',          // 洞察青
  RISK = '#EF4444'              // 警示红
}

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

  private constructor() {}

  static getInstance(): LiveAgentScheduler {
    if (!LiveAgentScheduler.instance) {
      LiveAgentScheduler.instance = new LiveAgentScheduler();
    }
    return LiveAgentScheduler.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: ['live_commerce', 'product_qa', 'sentiment_analysis', 'risk_detection']
    });

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

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

  private async registerAgents(): Promise<void> {
    // 1. 讲解智能体:基于LLM生成商品解说词
    await this.hmafSession?.registerAgent({
      agentId: 'presenter-1',
      agentType: AgentType.PRESENTER,
      capabilities: ['product_description', 'selling_point_extraction', 'script_generation'],
      modelConfig: {
        modelType: 'llm',
        temperature: 0.7,
        maxTokens: 512
      }
    });

    // 2. 互动智能体:NLP处理弹幕问答
    await this.hmafSession?.registerAgent({
      agentId: 'interaction-1',
      agentType: AgentType.INTERACTION,
      capabilities: ['intent_recognition', 'knowledge_retrieval', 'response_generation', 'sentiment_analysis'],
      modelConfig: {
        modelType: 'llm',
        temperature: 0.5,
        maxTokens: 256
      }
    });

    // 3. 洞察智能体:时序预测与数据洞察
    await this.hmafSession?.registerAgent({
      agentId: 'insight-1',
      agentType: AgentType.INSIGHT,
      capabilities: ['time_series_prediction', 'anomaly_detection', 'inventory_forecast'],
      modelConfig: {
        modelType: 'timeseries',
        predictionHorizon: 30  // 预测未来30分钟
      }
    });

    // 4. 风控智能体:敏感词与违规检测
    await this.hmafSession?.registerAgent({
      agentId: 'risk-1',
      agentType: AgentType.RISK,
      capabilities: ['sensitive_word_detection', 'content_moderation', 'compliance_check'],
      modelConfig: {
        modelType: 'classification',
        threshold: 0.85
      }
    });
  }

  // 主播发送讲解任务
  async sendPresentationTask(productId: string, style: string): Promise<string> {
    this.updateAgentState('presenter-1', AgentState.THINKING);
    
    const result = await this.hmafSession?.sendTask({
      targetAgent: 'presenter-1',
      taskType: 'generate_script',
      payload: {
        productId: productId,
        style: style,  // 'professional', 'casual', 'enthusiastic'
        duration: 60   // 60秒讲解词
      }
    });

    this.updateAgentState('presenter-1', AgentState.COMPLETED);
    return result?.content || '';
  }

  // 处理弹幕互动
  async handleDanmaku(danmakuText: string, userId: string): Promise<{ reply: string; sentiment: number }> {
    this.updateAgentState('interaction-1', AgentState.EXECUTING);
    
    // 先进行风控检测
    const riskResult = await this.hmafSession?.sendTask({
      targetAgent: 'risk-1',
      taskType: 'check_content',
      payload: { content: danmakuText }
    });

    if (riskResult?.isViolated) {
      this.updateAgentState('interaction-1', AgentState.ERROR);
      return { reply: '', sentiment: -1 };
    }

    // 意图识别与应答
    const intent = await this.intentEngine?.parseIntent(danmakuText);
    
    const reply = await this.hmafSession?.sendTask({
      targetAgent: 'interaction-1',
      taskType: 'generate_reply',
      payload: {
        intent: intent,
        originalText: danmakuText,
        userId: userId
      }
    });

    // 情感分析
    const sentimentResult = await this.hmafSession?.sendTask({
      targetAgent: 'interaction-1',
      taskType: 'analyze_sentiment',
      payload: { text: danmakuText }
    });

    this.updateAgentState('interaction-1', AgentState.COMPLETED);
    
    return {
      reply: reply?.content || '',
      sentiment: sentimentResult?.score || 0
    };
  }

  // 实时数据洞察
  async generateInsight(currentGMV: number, onlineCount: number): Promise<string> {
    this.updateAgentState('insight-1', AgentState.THINKING);
    
    const insight = await this.hmafSession?.sendTask({
      targetAgent: 'insight-1',
      taskType: 'generate_insight',
      payload: {
        currentGMV: currentGMV,
        onlineCount: onlineCount,
        timestamp: Date.now()
      }
    });

    this.updateAgentState('insight-1', AgentState.COMPLETED);
    return insight?.content || '';
  }

  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);
    });
  }
}

5.4 悬浮直播导航(LiveFloatNavigation.ets)

// entry/src/main/ets/components/LiveFloatNavigation.ets
import { window } from '@kit.ArkUI';
import { AgentState, AgentType, AgentPersonality } from '../agents/LiveAgentScheduler';
import { LivePhase, SentimentType } from './TrafficLightEffect';

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

@Component
export struct LiveFloatNavigation {
  @State currentIndex: number = 0;
  @State navTransparency: number = 0.70;
  @State isExpanded: boolean = false;
  @State bottomAvoidHeight: number = 0;
  @State onlineCount: number = 0;
  @State currentGMV: number = 0;
  @State livePhase: LivePhase = LivePhase.COLD_START;
  @State agentStates: Map<string, AgentState> = new Map([
    ['presenter-1', AgentState.IDLE],
    ['interaction-1', AgentState.IDLE],
    ['insight-1', AgentState.IDLE],
    ['risk-1', AgentState.IDLE]
  ]);

  private navItems: NavItem[] = [
    { id: 'live', icon: $r('app.media.ic_live'), label: '直播', page: 'LivePage' },
    { id: 'interaction', icon: $r('app.media.ic_chat'), label: '互动', page: 'InteractionPage', agentType: AgentType.INTERACTION },
    { id: 'data', icon: $r('app.media.ic_chart'), label: '数据', page: 'DataPage', agentType: AgentType.INSIGHT },
    { id: 'product', icon: $r('app.media.ic_package'), label: '商品', page: 'ProductPage', agentType: AgentType.PRESENTER },
    { 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('live_metrics', (metrics: { onlineCount: number; gmv: number }) => {
      this.onlineCount = metrics.onlineCount;
      this.currentGMV = metrics.gmv;
      this.updateLivePhase();
    });
  }

  private updateLivePhase(): void {
    if (this.onlineCount < 100) this.livePhase = LivePhase.COLD_START;
    else if (this.onlineCount < 1000) this.livePhase = LivePhase.GROWTH;
    else if (this.onlineCount < 10000) this.livePhase = LivePhase.EXPLOSION;
    else this.livePhase = LivePhase.PEAK;
  }

  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.PRESENTER]: 'presenter-1',
      [AgentType.INTERACTION]: 'interaction-1',
      [AgentType.INSIGHT]: 'insight-1',
      [AgentType.RISK]: 'risk-1'
    };
    
    return this.agentStates.get(agentIdMap[item.agentType]) || AgentState.IDLE;
  }

  private getPhaseColor(): string {
    const colors: Record<LivePhase, string> = {
      [LivePhase.COLD_START]: '#1E3A8A',
      [LivePhase.GROWTH]: '#10B981',
      [LivePhase.EXPLOSION]: '#F59E0B',
      [LivePhase.PEAK]: '#EF4444'
    };
    return colors[this.livePhase];
  }

  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.onlineCount.toLocaleString()}`)
                  .fontSize(13)
                  .fontColor('#FFFFFF')
                  .fontWeight(FontWeight.Bold)
                
                Text('在线观众')
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.6)')
              }
              .layoutWeight(1)

              Column() {
                Text(`¥${(this.currentGMV / 10000).toFixed(2)}`)
                  .fontSize(13)
                  .fontColor('#FCD34D')
                  .fontWeight(FontWeight.Bold)
                
                Text('实时GMV')
                  .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<LivePhase, string> = {
      [LivePhase.COLD_START]: '冷启动',
      [LivePhase.GROWTH]: '成长期',
      [LivePhase.EXPLOSION]: '爆发期',
      [LivePhase.PEAK]: '峰值期'
    };
    return labels[this.livePhase];
  }

  @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 弹幕互动面板(DanmakuPanel.ets)

// entry/src/main/ets/components/DanmakuPanel.ets
import { LiveAgentScheduler } from '../agents/LiveAgentScheduler';
import { SentimentType } from './TrafficLightEffect';

interface DanmakuItem {
  id: string;
  userId: string;
  nickname: string;
  content: string;
  sentiment: number;      // -1~1
  sentimentType: SentimentType;
  timestamp: number;
  isReply: boolean;       // 是否已自动回复
  replyContent?: string;
}

@Component
export struct DanmakuPanel {
  @State danmakuList: DanmakuItem[] = [];
  @State autoReplyEnabled: boolean = true;
  @State sentimentFilter: SentimentType | 'all' = 'all';
  private scheduler: LiveAgentScheduler = LiveAgentScheduler.getInstance();
  private listScroller: ListScroller = new ListScroller();

  aboutToAppear(): void {
    // 模拟弹幕数据接入
    this.startDanmakuSimulation();
  }

  private startDanmakuSimulation(): void {
    // 实际项目中应接入直播SDK的弹幕接口
    setInterval(() => {
      const mockDanmaku: DanmakuItem = {
        id: `dm_${Date.now()}`,
        userId: `user_${Math.floor(Math.random() * 1000)}`,
        nickname: `观众${Math.floor(Math.random() * 1000)}`,
        content: this.getMockContent(),
        sentiment: Math.random() * 2 - 1,
        sentimentType: this.calculateSentimentType(Math.random() * 2 - 1),
        timestamp: Date.now(),
        isReply: false
      };

      this.danmakuList.unshift(mockDanmaku);
      if (this.danmakuList.length > 100) {
        this.danmakuList.pop();
      }

      // 自动回复处理
      if (this.autoReplyEnabled && !mockDanmaku.isReply) {
        this.handleAutoReply(mockDanmaku);
      }

      // 同步情感光效到全局
      AppStorage.setOrCreate('current_sentiment', mockDanmaku.sentimentType);
    }, 2000);
  }

  private getMockContent(): string {
    const contents = [
      '这个多少钱?', '好用吗?', '已下单!', '主播讲解很详细',
      '质量怎么样?', '能便宜点吗?', '发货快吗?', '颜色有哪些?',
      '支持退换吗?', '想要链接', '太贵了', '比其他家贵',
      '已关注', '主播好美', '产品质量不错', '物流太慢了'
    ];
    return contents[Math.floor(Math.random() * contents.length)];
  }

  private calculateSentimentType(score: number): SentimentType {
    if (score > 0.6) return SentimentType.POSITIVE;
    if (score < -0.3) return SentimentType.NEGATIVE;
    return SentimentType.NEUTRAL;
  }

  private async handleAutoReply(danmaku: DanmakuItem): Promise<void> {
    const result = await this.scheduler.handleDanmaku(danmaku.content, danmaku.userId);
    
    if (result.reply) {
      const index = this.danmakuList.findIndex(item => item.id === danmaku.id);
      if (index !== -1) {
        this.danmakuList[index] = {
          ...this.danmakuList[index],
          isReply: true,
          replyContent: result.reply
        };
      }
    }
  }

  private getSentimentColor(type: SentimentType): string {
    const colors: Record<SentimentType, string> = {
      [SentimentType.POSITIVE]: '#FCD34D',
      [SentimentType.NEUTRAL]: '#9CA3AF',
      [SentimentType.NEGATIVE]: '#60A5FA'
    };
    return colors[type];
  }

  private getSentimentIcon(type: SentimentType): string {
    const icons: Record<SentimentType, string> = {
      [SentimentType.POSITIVE]: '👍',
      [SentimentType.NEUTRAL]: '💬',
      [SentimentType.NEGATIVE]: '⚠️'
    };
    return icons[type];
  }

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

      // 情感过滤标签
      Row({ space: 8 }) {
        this.buildFilterChip('全部', 'all');
        this.buildFilterChip('正面', SentimentType.POSITIVE);
        this.buildFilterChip('中性', SentimentType.NEUTRAL);
        this.buildFilterChip('负面', SentimentType.NEGATIVE);
      }
      .width('100%')
      .height(40)
      .padding({ left: 16, right: 16 })

      // 弹幕列表
      List({ scroller: this.listScroller }) {
        ForEach(this.getFilteredDanmaku(), (item: DanmakuItem) => {
          ListItem() {
            Column() {
              Row() {
                Text(`${this.getSentimentIcon(item.sentimentType)} ${item.nickname}`)
                  .fontSize(12)
                  .fontColor(this.getSentimentColor(item.sentimentType))
                  .fontWeight(FontWeight.Medium)

                Text(this.formatTime(item.timestamp))
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.4)')
              }
              .width('100%')
              .justifyContent(FlexAlign.SpaceBetween)

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

              if (item.isReply && item.replyContent) {
                Row() {
                  Text(`🤖 ${item.replyContent}`)
                    .fontSize(11)
                    .fontColor('#10B981')
                    .maxLines(1)
                    .textOverflow({ overflow: TextOverflow.Ellipsis })
                }
                .width('100%')
                .padding(8)
                .backgroundColor('rgba(16, 185, 129, 0.1)')
                .borderRadius(8)
                .margin({ top: 4 })
              }
            }
            .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: SentimentType | 'all'): void {
    const isSelected = this.sentimentFilter === 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.sentimentFilter = value;
      })
  }

  private getFilteredDanmaku(): DanmakuItem[] {
    if (this.sentimentFilter === 'all') return this.danmakuList;
    return this.danmakuList.filter(item => item.sentimentType === this.sentimentFilter);
  }

  private formatTime(timestamp: number): string {
    const date = new Date(timestamp);
    return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
  }
}

5.6 浮动数据看板窗口(DataDashboardWindow.ets)

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

@Component
export struct DataDashboardWindow {
  @State currentGMV: number = 0;
  @State targetGMV: number = 500000;  // 目标50万
  @State onlineCount: number = 0;
  @State peakOnline: number = 0;
  @State conversionRate: number = 0;
  @State avgWatchTime: number = 0;

  aboutToAppear(): void {
    // 监听实时数据
    AppStorage.watch('live_metrics', (metrics: { onlineCount: number; gmv: number }) => {
      this.onlineCount = metrics.onlineCount;
      this.currentGMV = metrics.gmv;
      
      if (metrics.onlineCount > this.peakOnline) {
        this.peakOnline = metrics.onlineCount;
      }
      
      // 模拟转化率与观看时长
      this.conversionRate = Math.min(15, 2 + metrics.onlineCount / 1000);
      this.avgWatchTime = Math.min(300, 30 + metrics.onlineCount / 100);
    });
  }

  private getGMVProgress(): number {
    return Math.min(100, (this.currentGMV / this.targetGMV) * 100);
  }

  private getProgressColor(): string {
    const progress = this.getGMVProgress();
    if (progress < 30) return '#60A5FA';
    if (progress < 70) return '#10B981';
    if (progress < 90) return '#F59E0B';
    return '#EF4444';
  }

  build() {
    Column() {
      // 标题栏
      Row() {
        Text('📊 实时数据看板')
          .fontSize(16)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Bold)
        
        Text('实时')
          .fontSize(11)
          .fontColor('#10B981')
          .backgroundColor('rgba(16, 185, 129, 0.2)')
          .padding({ left: 8, right: 8, top: 2, bottom: 2 })
          .borderRadius(10)
      }
      .width('100%')
      .height(50)
      .padding({ left: 16, right: 16 })
      .justifyContent(FlexAlign.SpaceBetween)

      // GMV进度环
      Stack() {
        // 背景圆环
        Circle()
          .width(140)
          .height(140)
          .fill('transparent')
          .stroke('rgba(255,255,255,0.1)')
          .strokeWidth(12)

        // 进度圆环
        Circle()
          .width(140)
          .height(140)
          .fill('transparent')
          .stroke(this.getProgressColor())
          .strokeWidth(12)
          .strokeDashArray([this.getGMVProgress() * 4.4, 440])
          .strokeLineCap(LineCapStyle.Round)
          .animation({
            duration: 1000,
            curve: Curve.EaseInOut
          })
          .shadow({
            radius: 15,
            color: this.getProgressColor(),
            offsetX: 0,
            offsetY: 0
          })

        // 中心数据
        Column() {
          Text(`¥${(this.currentGMV / 10000).toFixed(1)}`)
            .fontSize(20)
            .fontColor('#FFFFFF')
            .fontWeight(FontWeight.Bold)
          
          Text(`目标: ¥${(this.targetGMV / 10000).toFixed(0)}`)
            .fontSize(11)
            .fontColor('rgba(255,255,255,0.5)')
            .margin({ top: 4 })
        }
      }
      .width('100%')
      .height(180)
      .margin({ top: 16, bottom: 16 })

      // 关键指标网格
      Grid() {
        GridItem() {
          this.buildMetricCard('👥 在线人数', this.onlineCount.toLocaleString(), '#60A5FA')
        }
        
        GridItem() {
          this.buildMetricCard('📈 峰值在线', this.peakOnline.toLocaleString(), '#8B5CF6')
        }
        
        GridItem() {
          this.buildMetricCard('💰 转化率', `${this.conversionRate.toFixed(1)}%`, '#10B981')
        }
        
        GridItem() {
          this.buildMetricCard('⏱️ 平均观看', `${Math.floor(this.avgWatchTime / 60)}${this.avgWatchTime % 60}`, '#F59E0B')
        }
      }
      .columnsTemplate('1fr 1fr')
      .rowsTemplate('1fr 1fr')
      .width('100%')
      .height(200)
      .padding({ left: 12, right: 12 })
      .gap(12)

      // 智能体洞察建议
      Column() {
        Text('🤖 智能体洞察')
          .fontSize(14)
          .fontColor('#FFFFFF')
          .fontWeight(FontWeight.Medium)
          .margin({ bottom: 8 })

        Text(this.getInsightText())
          .fontSize(12)
          .fontColor('rgba(255,255,255,0.7)')
          .maxLines(3)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
      }
      .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)
  }

  @Builder
  buildMetricCard(label: string, value: string, color: string): void {
    Column() {
      Text(label)
        .fontSize(11)
        .fontColor('rgba(255,255,255,0.6)')
        .margin({ bottom: 8 })

      Text(value)
        .fontSize(18)
        .fontColor(color)
        .fontWeight(FontWeight.Bold)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('rgba(255,255,255,0.05)')
    .borderRadius(12)
    .justifyContent(FlexAlign.Center)
  }

  private getInsightText(): string {
    if (this.onlineCount < 100) {
      return '当前处于冷启动阶段,建议讲解智能体加强商品卖点输出,互动智能体主动发起话题引导评论。';
    } else if (this.conversionRate < 3) {
      return '流量增长但转化率偏低,洞察智能体分析发现用户价格敏感度较高,建议调整促销策略。';
    } else if (this.getGMVProgress() > 80) {
      return '即将达成今日GMV目标!建议风控智能体加强内容审核,确保冲刺阶段合规安全。';
    }
    return '直播数据表现平稳,四大智能体协同运行正常,继续保持当前节奏。';
  }
}

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`); // 12%透明度
      
      // 同步窗口阴影光效
      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 createDanmakuWindow(): Promise<window.Window> {
    const danmakuWindow = await window.createWindow({
      name: 'danmaku_float',
      windowType: window.WindowType.TYPE_FLOAT,
      ctx: getContext()
    });

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

    this.registerSubWindow('danmaku', danmakuWindow);
    return danmakuWindow;
  }

  // 创建浮动数据看板窗口
  async createDataWindow(): Promise<window.Window> {
    const dataWindow = await window.createWindow({
      name: 'data_float',
      windowType: window.WindowType.TYPE_FLOAT,
      ctx: getContext()
    });

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

    this.registerSubWindow('data', dataWindow);
    return dataWindow;
  }

  // 创建浮动商品橱窗窗口
  async createProductWindow(): Promise<window.Window> {
    const productWindow = await window.createWindow({
      name: 'product_float',
      windowType: window.WindowType.TYPE_FLOAT,
      ctx: getContext()
    });

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

    this.registerSubWindow('product', productWindow);
    return productWindow;
  }
}

5.8 主页面集成(LiveControlPage.ets)

// entry/src/main/ets/pages/LiveControlPage.ets
import { TrafficLightEffect, LivePhase, SentimentType } from '../components/TrafficLightEffect';
import { LiveFloatNavigation } from '../components/LiveFloatNavigation';
import { DanmakuPanel } from '../components/DanmakuPanel';
import { DataDashboardWindow } from '../windows/DataDashboardWindow';
import { WindowLightSync } from '../utils/WindowLightSync';
import { LiveAgentScheduler } from '../agents/LiveAgentScheduler';

@Entry
@Component
struct LiveControlPage {
  @State currentPage: string = 'LivePage';
  @State onlineCount: number = 156;
  @State currentGMV: number = 128000;
  @State currentSentiment: SentimentType = SentimentType.NEUTRAL;
  @State isLiveStarted: boolean = false;
  private windowSync: WindowLightSync = WindowLightSync.getInstance();
  private scheduler: LiveAgentScheduler = LiveAgentScheduler.getInstance();

  aboutToAppear(): async () => {
    // 初始化智能体调度器
    await this.scheduler.initialize();

    // 初始化窗口管理
    await this.initializeWindows();

    // 启动数据模拟
    this.startMetricsSimulation();

    // 监听页面切换
    AppStorage.watch('nav_page_change', (page: string) => {
      this.currentPage = page;
    });
  }

  private async initializeWindows(): Promise<void> {
    // 创建三个浮动子窗口
    await this.windowSync.createDanmakuWindow();
    await this.windowSync.createDataWindow();
    await this.windowSync.createProductWindow();
  }

  private startMetricsSimulation(): void {
    setInterval(() => {
      // 模拟流量波动
      const fluctuation = Math.floor(Math.random() * 50) - 20;
      this.onlineCount = Math.max(50, this.onlineCount + fluctuation);
      this.currentGMV += Math.floor(Math.random() * 5000);

      // 同步到全局状态
      AppStorage.setOrCreate('live_metrics', {
        onlineCount: this.onlineCount,
        gmv: this.currentGMV
      });

      // 同步光效
      const phase = this.getCurrentPhase();
      const themeColor = this.getPhaseColor(phase);
      this.windowSync.syncGlobalLightEffect(themeColor, this.getIntensityByGMV());
    }, 3000);
  }

  private getCurrentPhase(): LivePhase {
    if (this.onlineCount < 100) return LivePhase.COLD_START;
    if (this.onlineCount < 1000) return LivePhase.GROWTH;
    if (this.onlineCount < 10000) return LivePhase.EXPLOSION;
    return LivePhase.PEAK;
  }

  private getPhaseColor(phase: LivePhase): string {
    const colors: Record<LivePhase, string> = {
      [LivePhase.COLD_START]: '#1E3A8A',
      [LivePhase.GROWTH]: '#10B981',
      [LivePhase.EXPLOSION]: '#F59E0B',
      [LivePhase.PEAK]: '#EF4444'
    };
    return colors[phase];
  }

  private getIntensityByGMV(): number {
    const gmvSpeed = this.currentGMV / 100000; // 假设基准
    if (gmvSpeed > 50) return 1.0;
    if (gmvSpeed > 10) return 0.6;
    return 0.3;
  }

  build() {
    Stack() {
      // 底层:沉浸光效层
      TrafficLightEffect({
        onlineCount: this.onlineCount,
        gmvSpeed: this.currentGMV / 100000,
        sentiment: this.currentSentiment
      })

      // 中层:主内容区域
      Column() {
        this.buildHeader()
        
        Stack() {
          if (this.currentPage === 'LivePage') {
            this.buildLivePage()
          } else if (this.currentPage === 'InteractionPage') {
            DanmakuPanel()
          } else if (this.currentPage === 'DataPage') {
            DataDashboardWindow()
          } else if (this.currentPage === 'ProductPage') {
            this.buildProductPage()
          }
        }
        .layoutWeight(1)
      }
      .width('100%')
      .height('100%')

      // 顶层:悬浮导航
      LiveFloatNavigation({
        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.onlineCount.toLocaleString()} | GMV: ¥${(this.currentGMV / 10000).toFixed(2)}`)
          .fontSize(12)
          .fontColor('rgba(255,255,255,0.6)')
          .margin({ top: 4 })
      }
      .alignItems(HorizontalAlign.Start)

      Row({ space: 12 }) {
        Button(this.isLiveStarted ? '结束直播' : '开始直播')
          .fontSize(13)
          .fontColor('#FFFFFF')
          .backgroundColor(this.isLiveStarted ? '#EF4444' : '#10B981')
          .padding({ left: 20, right: 20, top: 8, bottom: 8 })
          .borderRadius(20)
          .onClick(() => {
            this.isLiveStarted = !this.isLiveStarted;
            if (this.isLiveStarted) {
              // 启动讲解智能体
              this.scheduler.sendPresentationTask('sku_001', 'enthusiastic');
            }
          })

        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
  buildLivePage(): void {
    Column() {
      // 直播画面占位(实际接入摄像头)
      Stack() {
        Column()
          .width('100%')
          .height('100%')
          .backgroundColor('rgba(255,255,255,0.05)')
          .borderRadius(16)

        if (!this.isLiveStarted) {
          Column() {
            Text('📹')
              .fontSize(48)
              .margin({ bottom: 16 })
            
            Text('点击"开始直播"启动智能体直播系统')
              .fontSize(14)
              .fontColor('rgba(255,255,255,0.6)')
          }
        } else {
          Column() {
            Text('🎥 直播中...')
              .fontSize(16)
              .fontColor('#10B981')
            
            Text('讲解智能体运行中 | 互动智能体待命')
              .fontSize(12)
              .fontColor('rgba(255,255,255,0.5)')
              .margin({ top: 8 })
          }
        }
      }
      .width('90%')
      .height(400)
      .margin({ top: 20, bottom: 20 })

      // 快捷操作区
      Row({ space: 16 }) {
        this.buildQuickAction('🎁', '发福袋', '#F59E0B');
        this.buildQuickAction('⚡', '秒杀', '#EF4444');
        this.buildQuickAction('🎫', '优惠券', '#8B5CF6');
        this.buildQuickAction('📢', '公告', '#06B6D4');
      }
      .margin({ bottom: 20 })
    }
    .width('100%')
    .height('100%')
  }

  @Builder
  buildQuickAction(icon: string, label: string, color: string): void {
    Column() {
      Text(icon)
        .fontSize(24)
        .margin({ bottom: 8 })
      
      Text(label)
        .fontSize(12)
        .fontColor('#FFFFFF')
    }
    .width(70)
    .height(80)
    .backgroundColor(`${color}20`)
    .borderRadius(16)
    .border({ width: 1, color: `${color}40` })
    .justifyContent(FlexAlign.Center)
    .onClick(() => {
      // 触发对应智能体任务
      AppStorage.setOrCreate('quick_action', { type: label, color });
    })
  }

  @Builder
  buildProductPage(): void {
    Column() {
      Text('🛍️ 商品橱窗管理')
        .fontSize(18)
        .fontColor('#FFFFFF')
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 20 })

      List() {
        ForEach([1, 2, 3, 4, 5], (index: number) => {
          ListItem() {
            Row() {
              Column() {
                Text(`商品 ${index}`)
                  .fontSize(14)
                  .fontColor('#FFFFFF')
                
                Text(`¥${(99 + index * 50).toFixed(2)}`)
                  .fontSize(12)
                  .fontColor('#F59E0B')
                  .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.sendPresentationTask(`sku_00${index}`, 'professional');
                })
            }
            .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: 'timeseries' 洞察智能体预测GMV趋势
内容审核 modelType: 'classification' 风控智能体违规检测

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 直播状态光效映射

直播阶段 在线人数 主题色 脉冲周期 光效强度
冷启动 <100 深海蓝 #1E3A8A 4秒 30%
成长期 100-1000 薄荷绿 #10B981 2秒 60%
爆发期 1000-10000 活力橙 #F59E0B 1秒 80%
峰值期 >10000 炽烈红 #EF4444 0.5秒 100%

6.4 智能体状态徽章动画

智能体状态 徽章颜色 动画效果 直播含义
空闲 #888888 静态 智能体待命
思考中 #8B5CF6 呼吸脉冲 LLM生成文案中
执行中 #F97316 旋转进度 处理弹幕/数据中
已完成 #10B981 静态 任务执行成功
异常 #EF4444 快速闪烁 风控触发/错误

6.5 性能优化建议

  1. 光效渲染优化:使用willChange: true标记频繁变化的动画层,避免全量重绘
  2. 智能体并发控制:通过maxConcurrentAgents: 4限制并发,防止资源争抢
  3. 弹幕列表虚拟化:当弹幕超过100条时,使用LazyForEach替代ForEach
  4. 窗口管理:子窗口使用TYPE_FLOAT类型,避免创建过多独立进程
  5. 数据节流:流量数据更新频率控制在3秒/次,避免UI频繁刷新

七、总结与展望

本文基于HarmonyOS 6(API 23)的HMAF智能体框架、悬浮导航与沉浸光感特性,构建了一套面向PC端电商直播的"直播智脑"系统。核心创新点包括:

  1. 四层智能体协作架构:讲解、互动、洞察、风控四大智能体通过HMAF的A2A模式实时协作,将主播从重复性工作中解放出来
  2. 流量脉搏光效系统:基于实时在线人数与GMV增速的动态光效渲染,让主播"看见"数据变化
  3. 悬浮直播导航:底部玻璃拟态导航承载四大模块,智能体状态徽章实时反馈,流量信息一键展开
  4. 多窗口光效联动:主窗口与三个浮动子窗口通过WindowLightSync实现跨窗口光效同步,焦点感知自动调节
  5. 弹幕情感光效:NLP实时分析弹幕情感,正面情绪触发暖光脉冲,负面情绪触发冷光警示

随着HarmonyOS生态的持续发展,直播智能体将向着"数字人主播"“多模态交互”"跨设备直播协作"等方向演进。HMAF框架的分布式能力与HarmonyOS的跨端协同特性,将为直播电商带来"一机控全场、多屏协同播"的全新体验。


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

Logo

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

更多推荐