文章目录
-
- 每日一句正能量
- 前言
- 一、前言:AI制药4.0时代的药物研发革新
- 二、技术架构与核心设计
-
- [2.1 系统架构设计](#2.1 系统架构设计)
- [2.2 分子活性光效映射体系](#2.2 分子活性光效映射体系)
- [2.3 靶点类型光效标识](#2.3 靶点类型光效标识)
- 三、核心代码实战
-
- [3.1 分子活性光效系统(MoleculeLightTheme.ets)](#3.1 分子活性光效系统(MoleculeLightTheme.ets))
- [3.2 HMAF四层药物研发智能体架构(DrugDiscoveryAgentScheduler.ets)](#3.2 HMAF四层药物研发智能体架构(DrugDiscoveryAgentScheduler.ets))
- [3.3 悬浮研发导航(DiscoveryFloatNavigation.ets)](#3.3 悬浮研发导航(DiscoveryFloatNavigation.ets))
- [3.4 主分子编辑器与3D可视化(MoleculeDesignPage.ets)](#3.4 主分子编辑器与3D可视化(MoleculeDesignPage.ets))
- [3.5 浮动活性热力图窗口(ActivityHeatmapAbility.ets)](#3.5 浮动活性热力图窗口(ActivityHeatmapAbility.ets))
- 四、关键技术总结
-
- [4.1 HMAF药物研发开发清单](#4.1 HMAF药物研发开发清单)
- [4.2 分子活性光效映射](#4.2 分子活性光效映射)
- [4.3 靶点类型光效标识](#4.3 靶点类型光效标识)
- 五、运行效果展示
-
- [5.1 靶点发现阶段 - 高活性光效](#5.1 靶点发现阶段 - 高活性光效)
- [5.2 分子生成阶段 - 中活性光效](#5.2 分子生成阶段 - 中活性光效)
- [5.3 活性评估阶段 - 毒性预警光效](#5.3 活性评估阶段 - 毒性预警光效)
- 六、总结与展望

每日一句正能量
"活得漂亮便是拥有一种此时此地的专注力。"
漂亮不是被人看见时的光鲜,而是你沉浸于当下时的神情。一个专注洗碗的人,可以比一个心不在焉走红毯的人更"漂亮"。专注力就是灵魂的聚光灯。
前言
摘要:2026年,中国创新药研发进入"AI驱动"时代,年均研发投入突破3000亿元,但传统药物研发面临靶点发现困难、分子筛选低效、临床试验设计复杂三大痛点。HarmonyOS 6(API 23)引入的鸿蒙智能体框架(HMAF)将AI能力下沉至系统层,配合悬浮导航与沉浸光感特性,为PC端药物研发与分子模拟带来了"分子即光效、活性即导航"的全新交互范式。本文将实战开发一款面向HarmonyOS PC的"药界智脑"应用,展示如何利用HMAF构建"靶点预测-分子生成-活性评估-临床试验设计"四层智能体协作架构,通过悬浮导航实现研发阶段实时追踪,基于沉浸光感打造"分子活性即氛围"的沉浸体验,以及基于多窗口架构构建浮动3D分子视窗、活性热力图面板和通路网络窗口的协作研发体验。
一、前言:AI制药4.0时代的药物研发革新
2026年,中国创新药研发进入"AI驱动"关键期。国家药监局(NMPA)年均批准创新药超过80个,AI辅助药物设计(AIDD)技术渗透率超过60%。但传统药物研发仍面临三大核心痛点:
-
靶点发现困难:人类基因组中潜在药物靶点超过3000个,但已验证的成药性靶点不足700个。传统生物信息学方法筛选靶点需要6-12个月,假阳性率高达40%,导致后期临床试验失败率居高不下
-
分子筛选低效:化学空间可探索的分子数量超过10^60个,传统高通量筛选(HTS)方法单次实验成本超过200万美元,筛选周期3-6个月,命中率仅0.01%-0.1%
-
临床试验设计复杂:III期临床试验需招募数千名患者,传统试验设计依赖统计学经验,难以动态优化入组标准,导致30%的临床试验因入组困难或终点设计不当而失败
HarmonyOS 6(API 23)的HMAF框架配合**悬浮导航(Float Navigation)与沉浸光感(Immersive Light Effects)**特性,为药物研发与分子模拟带来了革命性解决方案:
-
智能体协同研发:HMAF构建的"靶点预测智能体"可实时分析基因组与蛋白质组数据,自动识别高成药性靶点,响应延迟降至5秒;分子生成智能体基于扩散模型生成新颖分子结构,生成效率提升1000倍
-
分子活性光效感知:根据当前分子的生物活性预测(高活性/中活性/低活性/无活性/毒性预警)动态切换环境光色,让药物化学家"看见"分子的潜力
-
悬浮研发导航:底部悬浮导航实时显示四大智能体运行状态与研发进度徽章,研发人员无需切换页面即可掌握全局研发态势
-
PC多窗口协作研发:主分子编辑器 + 浮动3D分子视窗 + 浮动活性热力图面板 + 浮动通路网络窗口的四层架构,通过光效联动实现"一眼全局"
本文核心亮点:
-
分子活性光效:根据活性预测(高活性翠绿→中活性淡蓝→低活性暖黄→无活性灰白→毒性预警警示红)动态渲染全屏氛围光
-
靶点类型光效:激酶靶点(蓝紫)、GPCR靶点(橙红)、离子通道(青绿)、核受体(金黄)拥有专属光晕标识
-
悬浮研发导航:底部悬浮页签承载"靶点发现/分子生成/活性评估/临床设计"四大模块,实时显示活性统计徽章与分子数量脉冲
-
HMAF四层研发架构:预测智能体(靶点识别)、生成智能体(分子设计)、评估智能体(活性预测)、设计智能体(试验方案)协同工作
-
多窗口光效同步 :主窗口与三个浮动子窗口通过
AppStorage实现跨窗口光效联动,焦点感知自动调节
二、技术架构与核心设计
2.1 系统架构设计
┌─────────────────────────────────────────────────────────┐
│ 药界智脑 - 应用层 │
├─────────────┬─────────────┬─────────────┬──────────────┤
│ 靶点预测Agent │ 分子生成Agent │ 活性评估Agent │ 临床设计Agent │
├─────────────┴─────────────┴─────────────┴──────────────┤
│ HMAF 鸿蒙智能体框架(API 23) │
├─────────────────────────────────────────────────────────┤
│ 悬浮导航(Float Navigation) │ 沉浸光感(Immersive Light) │
├─────────────────────────────────────────────────────────┤
│ ArkUI / ArkTS / WebGL / Canvas 3D / Charts │
├─────────────────────────────────────────────────────────┤
│ HarmonyOS 6.1.0 (API 23) PC端 │
└─────────────────────────────────────────────────────────┘
2.2 分子活性光效映射体系
| 活性等级 | 主色调 | 环境光色 | 脉冲速度 | 心理感知 | 典型场景 |
|---|---|---|---|---|---|
| 高活性 | #27AE60 翠绿 |
#E8F8F0 淡绿 |
4000ms 极缓慢 | 优秀、候选 | IC50 < 10nM |
| 中活性 | #3498DB 淡蓝 |
#EBF5FB 淡蓝 |
3500ms 缓慢 | 正常、优化 | IC50 10-100nM |
| 低活性 | #F39C12 暖黄 |
#FEF5E7 淡黄 |
2500ms 中等 | 关注、改造 | IC50 100-1000nM |
| 无活性 | #95A5A6 灰白 |
#F5F5F5 浅灰 |
3000ms 缓慢 | 放弃、排除 | IC50 > 1000nM |
| 毒性预警 | #E74C3C 危险红 |
#FDEDEC 淡红 |
1000ms 急促 | 危险、终止 | hERG抑制>30% |
2.3 靶点类型光效标识
| 靶点类型 | 光晕颜色 | 材质效果 | 标识意义 |
|---|---|---|---|
| 激酶(Kinase) | #9B59B6 蓝紫 |
科技光泽 | 磷酸化信号 |
| GPCR | #E67E22 橙红 |
柔和漫反射 | 跨膜信号 |
| 离子通道 | #1ABC9C 青绿 |
流动光晕 | 离子通透 |
| 核受体 | #F1C40F 金黄 |
温暖辉光 | 基因调控 |
| 蛋白酶 | #E74C3C 深红 |
锐利光晕 | 催化切割 |
三、核心代码实战
3.1 分子活性光效系统(MoleculeLightTheme.ets)
代码亮点 :本模块实现了"分子活性即光效"的沉浸感知系统,这是"药界智脑"最核心的视觉创新。通过ActivityLevel枚举定义五种活性等级的专属光效人格,利用systemMaterialEffect为标题栏和导航组件注入物理光照级的光晕效果,结合动态呼吸光背景,实现药物化学家"一眼感知分子潜力"的直觉体验。
typescript
// entry/src/main/ets/theme/MoleculeLightTheme.ets
import { hdsMaterial, SystemMaterialEffect } from '@kit.UIDesignKit';
/**
* 分子活性等级枚举
*/
export enum ActivityLevel {
HIGH = 'high', // 高活性 - 翠绿
MEDIUM = 'medium', // 中活性 - 淡蓝
LOW = 'low', // 低活性 - 暖黄
INACTIVE = 'inactive', // 无活性 - 灰白
TOXIC = 'toxic' // 毒性预警 - 危险红
}
/**
* 光效配置接口
*/
export interface MoleculeLightConfig {
primaryColor: string;
ambientColor: string;
glowColor: string;
pulseSpeed: number;
pulseIntensity: number;
materialEffect: SystemMaterialEffect;
activityLabel: string;
}
/**
* 分子光效主题管理器
*/
export class MoleculeLightTheme {
private static readonly LIGHT_MAP: Record<ActivityLevel, MoleculeLightConfig> = {
[ActivityLevel.HIGH]: {
primaryColor: '#27AE60',
ambientColor: '#E8F8F0',
glowColor: '#7ED6A8',
pulseSpeed: 4000,
pulseIntensity: 0.15,
materialEffect: SystemMaterialEffect.IMMERSIVE,
activityLabel: '高活性 - 候选化合物'
},
[ActivityLevel.MEDIUM]: {
primaryColor: '#3498DB',
ambientColor: '#EBF5FB',
glowColor: '#85C1E9',
pulseSpeed: 3500,
pulseIntensity: 0.2,
materialEffect: SystemMaterialEffect.IMMERSIVE,
activityLabel: '中活性 - 需要优化'
},
[ActivityLevel.LOW]: {
primaryColor: '#F39C12',
ambientColor: '#FEF5E7',
glowColor: '#F8C471',
pulseSpeed: 2500,
pulseIntensity: 0.35,
materialEffect: SystemMaterialEffect.IMMERSIVE,
activityLabel: '低活性 - 结构改造'
},
[ActivityLevel.INACTIVE]: {
primaryColor: '#95A5A6',
ambientColor: '#F5F5F5',
glowColor: '#BDC3C7',
pulseSpeed: 3000,
pulseIntensity: 0.1,
materialEffect: SystemMaterialEffect.IMMERSIVE,
activityLabel: '无活性 - 排除'
},
[ActivityLevel.TOXIC]: {
primaryColor: '#E74C3C',
ambientColor: '#FDEDEC',
glowColor: '#FF6B6B',
pulseSpeed: 1000,
pulseIntensity: 0.7,
materialEffect: SystemMaterialEffect.IMMERSIVE,
activityLabel: '毒性预警 - 立即终止'
}
};
@StorageLink('currentActivityLevel') currentActivity: ActivityLevel = ActivityLevel.HIGH;
@StorageLink('ambientLightColor') ambientColor: string = '#E8F8F0';
@StorageLink('primaryLightColor') primaryColor: string = '#27AE60';
public switchActivityLight(level: ActivityLevel): void {
const config = MoleculeLightTheme.LIGHT_MAP[level];
this.currentActivity = level;
this.ambientColor = config.ambientColor;
this.primaryColor = config.primaryColor;
AppStorage.setOrCreate('lightEffectChanged', Date.now());
AppStorage.setOrCreate('activityLevelChanged', level);
}
public autoCalculateActivity(ic50: number, hergInhibition: number): ActivityLevel {
if (hergInhibition > 30) return ActivityLevel.TOXIC;
if (ic50 > 1000) return ActivityLevel.INACTIVE;
if (ic50 > 100) return ActivityLevel.LOW;
if (ic50 > 10) return ActivityLevel.MEDIUM;
return ActivityLevel.HIGH;
}
public getCurrentConfig(): MoleculeLightConfig {
return MoleculeLightTheme.LIGHT_MAP[this.currentActivity];
}
public getNavigationMaterial(): object {
const config = this.getCurrentConfig();
return {
systemMaterialEffect: {
materialType: hdsMaterial.MaterialType.ADAPTIVE,
materialLevel: hdsMaterial.MaterialLevel.ADAPTIVE,
effect: config.materialEffect
}
};
}
}
// 分子接口
export interface Molecule {
id: string;
smiles: string;
name: string;
molecularWeight: number;
logP: number;
tpsa: number;
ic50: number;
hergInhibition: number;
activityLevel: ActivityLevel;
targetType: string;
generation: number;
}
// 靶点接口
export interface DrugTarget {
id: string;
name: string;
targetType: 'kinase' | 'gpcr' | 'ion_channel' | 'nuclear_receptor' | 'protease';
uniprotId: string;
druggability: number;
relatedDiseases: string[];
}
export const moleculeLightTheme = new MoleculeLightTheme();
3.2 HMAF四层药物研发智能体架构(DrugDiscoveryAgentScheduler.ets)
代码亮点 :本模块是"药界智脑"的核心智能层,实现了"靶点预测-分子生成-活性评估-临床试验设计"四层智能体协作架构。通过Agent Framework Kit创建多智能体会话,四个Agent并行处理药物研发数据,结果实时汇聚到分子编辑器。关键创新在于利用Intents Kit解析药物化学家的研发意图(如"生成针对EGFR激酶的高选择性抑制剂"),自动触发对应Agent协作并调整界面活性光效。
typescript
// entry/src/main/ets/agents/DrugDiscoveryAgentScheduler.ets
import {
hmaf,
AgentSession,
AgentMode,
TaskMessage,
TaskResult
} from '@kit.AgentFrameworkKit';
import { intents, IntentEngine, IntentResult } from '@kit.IntentsKit';
import { moleculeLightTheme, ActivityLevel, Molecule, DrugTarget } from '../theme/MoleculeLightTheme';
export enum AgentType {
TARGET_PREDICTOR = 'target_predictor',
MOLECULE_GENERATOR = 'molecule_generator',
ACTIVITY_ASSESSOR = 'activity_assessor',
TRIAL_DESIGNER = 'trial_designer'
}
export enum DiscoveryStage {
TARGET_DISCOVERY = 'target_discovery',
MOLECULE_GENERATION = 'molecule_generation',
ACTIVITY_EVALUATION = 'activity_evaluation',
CLINICAL_DESIGN = 'clinical_design'
}
export interface TargetPrediction {
targetId: string;
confidence: number;
druggabilityScore: number;
competitiveLandscape: string[];
biomarkerPotential: number;
}
export class DrugDiscoveryAgentScheduler {
private session: AgentSession | null = null;
private intentEngine: IntentEngine | null = null;
private molecules: Map<string, Molecule> = new Map();
private targets: Map<string, DrugTarget> = new Map();
private predictions: Map<string, TargetPrediction> = new Map();
private onTargetPredicted?: (prediction: TargetPrediction) => void;
private onMoleculesGenerated?: (molecules: Molecule[]) => void;
private onActivityAssessed?: (assessments: ActivityAssessment[]) => void;
private onTrialDesigned?: (trial: ClinicalTrial) => void;
private onStageChanged?: (stage: DiscoveryStage) => void;
public async initialize(): Promise<void> {
this.session = await hmaf.createAgentSession({
mode: AgentMode.MULTI_AGENT,
config: {
maxConcurrentAgents: 4,
timeout: 180000,
enableDistributed: true
}
});
this.intentEngine = await intents.createIntentEngine({
supportedDomains: ['drug_discovery', 'target_prediction', 'molecule_design', 'clinical_trial']
});
await this.registerAgents();
console.info('DrugDiscoveryAgentScheduler initialized');
}
private async registerAgents(): Promise<void> {
if (!this.session) return;
// 1. 靶点预测Agent
await this.session.registerAgent({
agentId: AgentType.TARGET_PREDICTOR,
capabilities: ['genomic_analysis', 'proteomic_analysis', 'druggability_prediction', 'competitive_intelligence'],
promptTemplate: `
你是药物靶点预测专家。基于多组学数据预测高成药性靶点:
- 基因组学:基因表达谱、突变频率、拷贝数变异
- 蛋白质组学:蛋白质结构、相互作用网络、翻译后修饰
- 成药性评估:可药性口袋、选择性指数、安全性预测
- 竞争格局:已有药物、在研管线、专利布局
返回JSON格式: {
"targetId": "EGFR",
"confidence": 0.92,
"druggabilityScore": 0.85,
"competitiveLandscape": ["gefitinib", "osimertinib"],
"biomarkerPotential": 0.88
}
`
});
// 2. 分子生成Agent
await this.session.registerAgent({
agentId: AgentType.MOLECULE_GENERATOR,
capabilities: ['diffusion_model', 'fragment_assembly', 'scaffold_hopping', 'property_optimization'],
promptTemplate: `
你是AI分子生成专家。基于靶点结构生成新颖候选分子:
- 扩散模型:基于靶点口袋形状生成3D分子构象
- 片段组装:组合已知活性片段构建新骨架
- 骨架跃迁:保持活性同时改变核心结构规避专利
- 性质优化:同时优化活性、选择性、ADMET性质
返回JSON格式: [{"id": "mol_1", "smiles": "CCOc1cc2ncnc(Nc3ccc(F)c(Cl)c3)c2cc1O", "ic50": 5.2, "hergInhibition": 8.5}]
`
});
// 3. 活性评估Agent
await this.session.registerAgent({
agentId: AgentType.ACTIVITY_ASSESSOR,
capabilities: ['binding_affinity', 'selectivity_profile', 'admet_prediction', 'toxicity_alert'],
promptTemplate: `
你是分子活性评估专家。综合评估候选分子的成药性:
- 结合亲和力:Kd/Ki/IC50预测
- 选择性谱:kinome扫描、脱靶效应
- ADMET:吸收、分布、代谢、排泄、毒性
- 毒性预警:hERG、肝毒性、基因毒性
返回JSON格式: [{"moleculeId": "mol_1", "ic50": 5.2, "selectivity": 120, "hergInhibition": 8.5, "activityLevel": "high"}]
`
});
// 4. 临床设计Agent
await this.session.registerAgent({
agentId: AgentType.TRIAL_DESIGNER,
capabilities: ['patient_stratification', 'endpoint_selection', 'dose_optimization', 'adaptive_design'],
promptTemplate: `
你是临床试验设计专家。优化临床试验方案:
- 患者分层:基于生物标志物的精准入组
- 终点选择:主要终点/次要终点/探索性终点
- 剂量优化:MTD确定、RP2D推荐
- 适应性设计:期中分析、样本量重估
返回JSON格式: {"trialPhase": "I/II", "indication": "NSCLC EGFR T790M+", "primaryEndpoint": "ORR", "sampleSize": 120}
`
});
}
public async processDiscoveryIntent(input: string, researchData: object): Promise<void> {
if (!this.session || !this.intentEngine) throw new Error('Not initialized');
const intentResult: IntentResult = await this.intentEngine.parseIntent(input);
const intent = intentResult.primaryIntent;
console.info(`Detected discovery intent: ${intent.domain}/${intent.action}`);
this.adjustStageByIntent(intent);
switch (intent.action) {
case 'predict_target':
await this.dispatchTargetPrediction(researchData);
break;
case 'generate_molecules':
await this.dispatchMoleculeGeneration(researchData);
break;
case 'assess_activity':
await this.dispatchActivityAssessment(Array.from(this.molecules.values()));
break;
case 'design_trial':
await this.dispatchTrialDesign(Array.from(this.molecules.values()));
break;
case 'full_discovery':
await this.dispatchFullDiscovery(researchData);
break;
default:
await this.dispatchFullDiscovery(researchData);
}
}
private adjustStageByIntent(intent: IntentResult['primaryIntent']): void {
const stageMap: Record<string, DiscoveryStage> = {
'predict_target': DiscoveryStage.TARGET_DISCOVERY,
'generate_molecules': DiscoveryStage.MOLECULE_GENERATION,
'assess_activity': DiscoveryStage.ACTIVITY_EVALUATION,
'design_trial': DiscoveryStage.CLINICAL_DESIGN
};
this.onStageChanged?.(stageMap[intent.action] || DiscoveryStage.TARGET_DISCOVERY);
}
private async dispatchTargetPrediction(researchData: object): Promise<void> {
const task: TaskMessage = {
targetAgent: AgentType.TARGET_PREDICTOR,
taskType: 'predict',
payload: researchData,
priority: 1
};
const result = await this.session!.sendTask(task);
const prediction: TargetPrediction = JSON.parse(result.data);
this.predictions.set(prediction.targetId, prediction);
this.onTargetPredicted?.(prediction);
AppStorage.setOrCreate('targetPrediction', prediction);
}
private async dispatchMoleculeGeneration(targetData: object): Promise<void> {
const task: TaskMessage = {
targetAgent: AgentType.MOLECULE_GENERATOR,
taskType: 'generate',
payload: targetData,
priority: 2
};
const result = await this.session!.sendTask(task);
const generatedMolecules: Molecule[] = JSON.parse(result.data);
generatedMolecules.forEach(mol => {
mol.activityLevel = moleculeLightTheme.autoCalculateActivity(mol.ic50, mol.hergInhibition);
this.molecules.set(mol.id, mol);
});
this.onMoleculesGenerated?.(generatedMolecules);
AppStorage.setOrCreate('generatedMolecules', generatedMolecules);
}
private async dispatchActivityAssessment(molecules: Molecule[]): Promise<void> {
const task: TaskMessage = {
targetAgent: AgentType.ACTIVITY_ASSESSOR,
taskType: 'assess',
payload: { molecules },
priority: 3
};
const result = await this.session!.sendTask(task);
const assessments: ActivityAssessment[] = JSON.parse(result.data);
// 更新分子活性并切换光效
const bestMolecule = molecules.reduce((best, mol) =>
mol.ic50 < best.ic50 ? mol : best
);
moleculeLightTheme.switchActivityLight(bestMolecule.activityLevel);
this.onActivityAssessed?.(assessments);
AppStorage.setOrCreate('activityAssessments', assessments);
}
private async dispatchTrialDesign(molecules: Molecule[]): Promise<void> {
const task: TaskMessage = {
targetAgent: AgentType.TRIAL_DESIGNER,
taskType: 'design',
payload: { leadMolecule: molecules[0], target: Array.from(this.targets.values())[0] },
priority: 4
};
const result = await this.session!.sendTask(task);
const trial: ClinicalTrial = JSON.parse(result.data);
this.onTrialDesigned?.(trial);
AppStorage.setOrCreate('clinicalTrial', trial);
}
private async dispatchFullDiscovery(researchData: object): Promise<void> {
await this.dispatchTargetPrediction(researchData);
const target = Array.from(this.targets.values())[0];
await this.dispatchMoleculeGeneration({ target });
const allMolecules = Array.from(this.molecules.values());
await this.dispatchActivityAssessment(allMolecules);
await this.dispatchTrialDesign(allMolecules);
}
public setCallbacks(callbacks: object): void {
Object.assign(this, callbacks);
}
public getDiscoveryData(): object {
return {
molecules: Array.from(this.molecules.values()),
targets: Array.from(this.targets.values()),
predictions: Array.from(this.predictions.values())
};
}
}
export interface ActivityAssessment {
moleculeId: string;
ic50: number;
selectivity: number;
hergInhibition: number;
activityLevel: ActivityLevel;
admetScore: number;
}
export interface ClinicalTrial {
trialPhase: string;
indication: string;
primaryEndpoint: string;
sampleSize: number;
estimatedDuration: number;
biomarkerStratification: boolean;
}
export const drugDiscoveryAgentScheduler = new DrugDiscoveryAgentScheduler();
3.3 悬浮研发导航(DiscoveryFloatNavigation.ets)
代码亮点 :本模块实现了"研发阶段即导航"的悬浮页签系统。底部悬浮导航承载"靶点发现-分子生成-活性评估-临床设计"四个研发阶段,实时显示活性统计徽章和分子数量角标。采用HdsTabs悬浮样式配合systemMaterialEffect实现玻璃拟态+活性光效的双重效果。
typescript
// entry/src/main/ets/components/DiscoveryFloatNavigation.ets
import { HdsTabs, HdsTabsController, hdsMaterial } from '@kit.UIDesignKit';
import { moleculeLightTheme, ActivityLevel } from '../theme/MoleculeLightTheme';
import { DiscoveryStage } from '../agents/DrugDiscoveryAgentScheduler';
@Component
export struct DiscoveryFloatNavigation {
@StorageLink('currentDiscoveryStage') currentStage: DiscoveryStage = DiscoveryStage.TARGET_DISCOVERY;
@StorageLink('currentActivityLevel') currentActivity: ActivityLevel = ActivityLevel.HIGH;
@StorageLink('primaryLightColor') primaryColor: string = '#27AE60';
@StorageLink('navTransparency') navTransparency: number = 0.75;
@State moleculeStats: { total: number; highActivity: number; mediumActivity: number; toxic: number } =
{ total: 0, highActivity: 0, mediumActivity: 0, toxic: 0 };
private hdsTabController: HdsTabsController = new HdsTabsController();
private readonly STAGE_CONFIG: Record<DiscoveryStage, { color: string; icon: Resource; label: string }> = {
[DiscoveryStage.TARGET_DISCOVERY]: { color: '#9B59B6', icon: $r('app.media.icon_target'), label: '靶点发现' },
[DiscoveryStage.MOLECULE_GENERATION]: { color: '#3498DB', icon: $r('app.media.icon_molecule'), label: '分子生成' },
[DiscoveryStage.ACTIVITY_EVALUATION]: { color: '#27AE60', icon: $r('app.media.icon_activity'), label: '活性评估' },
[DiscoveryStage.CLINICAL_DESIGN]: { color: '#E67E22', icon: $r('app.media.icon_clinical'), label: '临床设计' }
};
aboutToAppear(): void {
AppStorage.link('moleculeStats').onChange((value: typeof this.moleculeStats) => {
this.moleculeStats = value;
});
}
build() {
Column() {
this.ActivityPulseIndicator()
HdsTabs({
controller: this.hdsTabController,
barPosition: BarPosition.End
}) {
TabContent() { this.TargetDiscoveryContent() }
.tabBar(this.buildStageTabBar('靶点', DiscoveryStage.TARGET_DISCOVERY, 0))
TabContent() { this.MoleculeGenContent() }
.tabBar(this.buildStageTabBar('分子', DiscoveryStage.MOLECULE_GENERATION,
this.moleculeStats.total))
TabContent() { this.ActivityEvalContent() }
.tabBar(this.buildStageTabBar('活性', DiscoveryStage.ACTIVITY_EVALUATION,
this.moleculeStats.highActivity))
TabContent() { this.ClinicalDesignContent() }
.tabBar(this.buildStageTabBar('临床', DiscoveryStage.CLINICAL_DESIGN, 0))
}
.width('96%')
.height(72)
.backgroundColor(`rgba(255, 255, 255, ${this.navTransparency})`)
.borderRadius(20)
.shadow({ radius: 16, color: 'rgba(0, 0, 0, 0.12)', offsetX: 0, offsetY: 4 })
.barFloatingStyle({
barBottomMargin: 16,
gradientMask: { maskColor: '#66F1F3F5', maskHeight: 92 },
systemMaterialEffect: {
materialType: hdsMaterial.MaterialType.ADAPTIVE,
materialLevel: hdsMaterial.MaterialLevel.ADAPTIVE
}
})
.border({ width: 1.5, color: this.primaryColor + '44', radius: 20 })
}
.width('100%')
.padding({ bottom: 12 })
}
@Builder
ActivityPulseIndicator(): void {
Row() {
Row()
.width(48)
.height(4)
.backgroundColor(this.primaryColor)
.borderRadius(2)
.shadow({ radius: 8, color: this.primaryColor + '66' })
.animation({
duration: moleculeLightTheme.getCurrentConfig().pulseSpeed,
iterations: -1,
curve: Curve.EaseInOut
})
.opacity(0.5 + Math.sin(AppStorage.get<number>('activityPulsePhase') || 0) *
moleculeLightTheme.getCurrentConfig().pulseIntensity)
}
.width('100%')
.justifyContent(FlexAlign.Center)
.margin({ bottom: 8 })
}
@Builder
buildStageTabBar(title: string, stage: DiscoveryStage, badgeCount: number): void {
Column() {
Stack() {
Image(this.STAGE_CONFIG[stage].icon)
.width(24)
.height(24)
.fillColor(this.currentStage === stage ? this.STAGE_CONFIG[stage].color : '#666666')
if (badgeCount > 0) {
Text(badgeCount.toString())
.fontSize(10)
.fontColor('#FFFFFF')
.backgroundColor(stage === DiscoveryStage.ACTIVITY_EVALUATION ? '#27AE60' : this.STAGE_CONFIG[stage].color)
.borderRadius(8)
.padding({ left: 4, right: 4 })
.position({ x: 16, y: -6 })
}
}
.width(32)
.height(32)
Text(title)
.fontSize(12)
.fontColor(this.currentStage === stage ? this.STAGE_CONFIG[stage].color : '#999999')
.margin({ top: 4 })
}
.width('100%')
.onClick(() => {
this.currentStage = stage;
AppStorage.setOrCreate('discoveryStageChanged', stage);
})
}
@Builder TargetDiscoveryContent(): void {}
@Builder MoleculeGenContent(): void {}
@Builder ActivityEvalContent(): void {}
@Builder ClinicalDesignContent(): void {}
}
3.4 主分子编辑器与3D可视化(MoleculeDesignPage.ets)
代码亮点 :本模块实现了分子结构的核心编辑与3D可视化层。基于RichEditor组件实现SMILES字符串编辑,通过WebGL渲染3D分子球棍模型,每个原子根据元素类型渲染专属颜色,分子整体根据活性等级渲染环境光晕。关键创新在于"活性分子呼吸光"------高活性分子在3D视窗中以翠绿光晕脉冲闪烁,毒性分子以红色警示光急促闪烁。
typescript
// entry/src/main/ets/pages/MoleculeDesignPage.ets
import { RichEditor, RichEditorController } from '@kit.ArkUI';
import { window } from '@kit.WindowManagerKit';
import { moleculeLightTheme, ActivityLevel, Molecule, DrugTarget } from '../theme/MoleculeLightTheme';
import { drugDiscoveryAgentScheduler, DiscoveryStage, TargetPrediction } from '../agents/DrugDiscoveryAgentScheduler';
import { DiscoveryFloatNavigation } from '../components/DiscoveryFloatNavigation';
@Entry
@Component
struct MoleculeDesignPage {
@StorageLink('currentActivityLevel') currentActivity: ActivityLevel = ActivityLevel.HIGH;
@StorageLink('ambientLightColor') ambientColor: string = '#E8F8F0';
@StorageLink('primaryLightColor') primaryColor: string = '#27AE60';
@StorageLink('currentDiscoveryStage') currentStage: DiscoveryStage = DiscoveryStage.TARGET_DISCOVERY;
@State molecules: Molecule[] = [];
@State targets: DrugTarget[] = [];
@State prediction: TargetPrediction | null = null;
@State selectedMoleculeId: string = '';
@State isDiscovering: boolean = false;
@State pulsePhase: number = 0;
private smilesController: RichEditorController = new RichEditorController();
private readonly ELEMENT_COLORS: Record<string, string> = {
'C': '#333333', 'N': '#3050F8', 'O': '#FF0D0D', 'S': '#FFFF30',
'P': '#FF8000', 'F': '#90E050', 'Cl': '#1FF01F', 'Br': '#A62929'
};
aboutToAppear(): void {
drugDiscoveryAgentScheduler.initialize().then(() => {
drugDiscoveryAgentScheduler.setCallbacks({
onTargetPredicted: (pred) => { this.prediction = pred; },
onMoleculesGenerated: (newMols) => {
this.molecules = newMols;
// 更新统计
const stats = {
total: newMols.length,
highActivity: newMols.filter(m => m.activityLevel === ActivityLevel.HIGH).length,
mediumActivity: newMols.filter(m => m.activityLevel === ActivityLevel.MEDIUM).length,
toxic: newMols.filter(m => m.activityLevel === ActivityLevel.TOXIC).length
};
AppStorage.setOrCreate('moleculeStats', stats);
},
onActivityAssessed: (assessments) => {
// 切换到最佳分子的活性光效
const best = this.molecules.reduce((b, m) => m.ic50 < b.ic50 ? m : b);
moleculeLightTheme.switchActivityLight(best.activityLevel);
},
onStageChanged: (stage) => { this.currentStage = stage; }
});
});
this.startActivityPulseAnimation();
this.loadDemoDiscovery();
this.setupImmersiveWindow();
}
private startActivityPulseAnimation(): void {
const animate = () => {
this.pulsePhase = (this.pulsePhase + 0.03) % (Math.PI * 2);
AppStorage.setOrCreate('activityPulsePhase', this.pulsePhase);
requestAnimationFrame(animate);
};
animate();
}
private async loadDemoDiscovery(): Promise<void> {
const demoData = {
disease: '非小细胞肺癌',
targetHint: 'EGFR T790M突变',
knownInhibitors: ['gefitinib', 'osimertinib']
};
this.isDiscovering = true;
await drugDiscoveryAgentScheduler.processDiscoveryIntent('发现针对EGFR T790M的新型抑制剂', demoData);
this.isDiscovering = false;
}
private async setupImmersiveWindow(): Promise<void> {
const win = await window.getLastWindow(getContext());
await win.setWindowLayoutFullScreen(true);
await win.setWindowSystemBarEnable([]);
await win.setWindowBackgroundColor('#00000000');
await win.setWindowMinWidth(1600);
await win.setWindowMinHeight(1000);
}
private async openMolecule3DWindow(): Promise<void> {
const mol = this.molecules.find(m => m.id === this.selectedMoleculeId);
if (!mol) return;
const want = {
deviceId: '',
bundleName: getContext().applicationInfo.name,
abilityName: 'Molecule3DAbility',
parameters: { moleculeData: JSON.stringify(mol) }
};
await getContext().startAbility(want);
}
private async openActivityHeatmapWindow(): Promise<void> {
const want = {
deviceId: '',
bundleName: getContext().applicationInfo.name,
abilityName: 'ActivityHeatmapAbility',
parameters: { moleculesData: JSON.stringify(this.molecules) }
};
await getContext().startAbility(want);
}
private async openPathwayNetworkWindow(): Promise<void> {
const want = {
deviceId: '',
bundleName: getContext().applicationInfo.name,
abilityName: 'PathwayNetworkAbility',
parameters: { targetData: JSON.stringify(this.targets) }
};
await getContext().startAbility(want);
}
build() {
Stack() {
Column()
.width('100%')
.height('100%')
.backgroundColor(this.ambientColor)
.animation({ duration: 800, curve: Curve.EaseInOut })
Column() {
Row() {
Row() {
Circle()
.width(10)
.height(10)
.fill(this.primaryColor)
.shadow({ radius: 6, color: this.primaryColor + '80' })
Text(moleculeLightTheme.getCurrentConfig().activityLabel)
.fontSize(13)
.fontColor(this.primaryColor)
.margin({ left: 6 })
}
Blank()
Text('药界智脑')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#333333')
Blank()
Row({ space: 12 }) {
Button('3D分子')
.fontSize(12)
.backgroundColor(this.primaryColor + '1A')
.fontColor(this.primaryColor)
.borderRadius(6)
.onClick(() => this.openMolecule3DWindow())
Button('活性热力图')
.fontSize(12)
.backgroundColor(this.primaryColor + '1A')
.fontColor(this.primaryColor)
.borderRadius(6)
.onClick(() => this.openActivityHeatmapWindow())
Button('通路网络')
.fontSize(12)
.backgroundColor(this.primaryColor + '1A')
.fontColor(this.primaryColor)
.borderRadius(6)
.onClick(() => this.openPathwayNetworkWindow())
}
}
.width('100%')
.height(56)
.padding({ left: 24, right: 24 })
.backgroundColor('rgba(255, 255, 255, 0.85)')
.backdropFilter($r('sys.blur.20'))
.alignItems(VerticalAlign.Center)
if (this.prediction) {
Row() {
Text(`靶点:${this.prediction.targetId}`)
.fontSize(11)
.fontColor('#666666')
Text(`成药性:${(this.prediction.druggabilityScore * 100).toFixed(0)}%`)
.fontSize(11)
.fontColor('#666666')
.margin({ left: 16 })
Text(`置信度:${(this.prediction.confidence * 100).toFixed(0)}%`)
.fontSize(11)
.fontColor(this.primaryColor)
.margin({ left: 16 })
if (this.isDiscovering) {
Text('研发中...')
.fontSize(11)
.fontColor(this.primaryColor)
.margin({ left: 16 })
.animation({
duration: 1000,
iterations: -1,
curve: Curve.EaseInOut
})
.opacity(0.5 + Math.sin(this.pulsePhase) * 0.5)
}
}
.width('100%')
.height(36)
.padding({ left: 24, right: 24 })
.backgroundColor('rgba(255, 255, 255, 0.6)')
}
// 分子列表 + SMILES编辑器
Row() {
// 分子列表
List() {
ForEach(this.molecules, (mol: Molecule) => {
ListItem() {
Column() {
Row() {
Text(mol.name || mol.id)
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
Blank()
Text(`${mol.ic50.toFixed(1)}nM`)
.fontSize(12)
.fontColor(mol.ic50 < 10 ? '#27AE60' : mol.ic50 < 100 ? '#3498DB' : '#F39C12')
}
.width('100%')
Text(mol.smiles)
.fontSize(10)
.fontColor('#999999')
.margin({ top: 4 })
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
Row() {
Text(`MW: ${mol.molecularWeight.toFixed(1)}`)
.fontSize(10)
.fontColor('#999999')
Text(`LogP: ${mol.logP.toFixed(2)}`)
.fontSize(10)
.fontColor('#999999')
.margin({ left: 8 })
Text(`hERG: ${mol.hergInhibition.toFixed(1)}%`)
.fontSize(10)
.fontColor(mol.hergInhibition > 30 ? '#E74C3C' : '#999999')
.margin({ left: 8 })
}
.margin({ top: 6 })
}
.width('100%')
.padding(12)
.backgroundColor(this.selectedMoleculeId === mol.id ? this.primaryColor + '1A' : '#FFFFFF')
.borderRadius(8)
.border({ width: 1, color: this.selectedMoleculeId === mol.id ? this.primaryColor + '4D' : '#F0F0F0', radius: 8 })
.onClick(() => {
this.selectedMoleculeId = mol.id;
moleculeLightTheme.switchActivityLight(mol.activityLevel);
})
}
})
}
.width('35%')
.height('100%')
.padding(12)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.margin(16)
.shadow({ radius: 8, color: 'rgba(0, 0, 0, 0.04)', offsetX: 0, offsetY: 2 })
// SMILES编辑器 + 2D结构预览
Column() {
Text('SMILES 编辑器')
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor('#333333')
.alignSelf(ItemAlign.Start)
.margin({ bottom: 8 })
RichEditor({ controller: this.smilesController })
.width('100%')
.height(80)
.padding(12)
.backgroundColor('#F8F9FA')
.borderRadius(8)
.border({ width: 1, color: '#E9ECEF' })
// 2D分子结构预览区(Canvas绘制简化结构)
Canvas()
.width('100%')
.layoutWeight(1)
.backgroundColor('#FFFFFF')
.borderRadius(8)
.margin({ top: 12 })
.shadow({ radius: 8, color: 'rgba(0, 0, 0, 0.04)', offsetX: 0, offsetY: 2 })
}
.width('60%')
.height('100%')
.padding(16)
.backgroundColor('#FFFFFF')
.borderRadius(12)
.margin({ top: 16, bottom: 16, right: 16 })
.shadow({ radius: 12, color: 'rgba(0, 0, 0, 0.06)', offsetX: 0, offsetY: 4 })
}
.width('100%')
.layoutWeight(1)
Column() {
DiscoveryFloatNavigation()
}
.width('100%')
}
.width('100%')
.height('100%')
}
.width('100%')
.height('100%')
}
}
3.5 浮动活性热力图窗口(ActivityHeatmapAbility.ets)
代码亮点:本模块实现了浮动活性热力图窗口,按IC50值和选择性绘制分子活性分布热力图。热力图颜色从绿色(高活性)到红色(毒性)渐变,与主窗口的活性光效系统保持一致。支持点击热力图单元格自动定位到对应分子并同步切换光效。
typescript
// entry/src/main/ets/heatmapability/ActivityHeatmapAbility.ets
import { window } from '@kit.WindowManagerKit';
import { moleculeLightTheme, ActivityLevel, Molecule } from '../theme/MoleculeLightTheme';
@Entry
@Component
struct ActivityHeatmapPage {
@StorageLink('currentActivityLevel') currentActivity: ActivityLevel = ActivityLevel.HIGH;
@StorageLink('primaryLightColor') primaryColor: string = '#27AE60';
@State molecules: Molecule[] = [];
@State isWindowFocused: boolean = true;
@State selectedCell: string = '';
aboutToAppear(): void {
const params = getContext().abilityInfo?.parameters;
if (params?.moleculesData) {
this.molecules = JSON.parse(params.moleculesData);
}
this.setupFocusListener();
}
private async setupFocusListener(): Promise<void> {
const win = await window.getLastWindow(getContext());
win.on('windowFocusChange', (isFocused: boolean) => {
this.isWindowFocused = isFocused;
});
}
private getHeatmapColor(ic50: number, herg: number): string {
if (herg > 30) return '#E74C3C';
if (ic50 < 10) return '#27AE60';
if (ic50 < 100) return '#3498DB';
if (ic50 < 1000) return '#F39C12';
return '#95A5A6';
}
build() {
Column() {
Row() {
Circle().width(10).height(10).fill(this.primaryColor)
.shadow({ radius: 6, color: this.primaryColor + '80' })
Text('活性热力图').fontSize(16).fontWeight(FontWeight.Bold).fontColor('#333333').margin({ left: 8 })
Blank()
Text(`${this.molecules.length}个分子`).fontSize(12).fontColor('#999999')
}
.width('100%').height(48).padding({ left: 16, right: 16 })
.backgroundColor('rgba(255, 255, 255, 0.9)')
.borderRadius({ topLeft: 16, topRight: 16 })
Grid() {
ForEach(this.molecules, (mol: Molecule) => {
GridItem() {
Column() {
Text(mol.id)
.fontSize(10)
.fontColor('#FFFFFF')
.maxLines(1)
Text(`${mol.ic50.toFixed(1)}`)
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.margin({ top: 4 })
Text('nM')
.fontSize(9)
.fontColor('#FFFFFF')
.opacity(0.8)
}
.width('100%')
.height('100%')
.padding(8)
.backgroundColor(this.getHeatmapColor(mol.ic50, mol.hergInhibition))
.borderRadius(8)
.opacity(this.selectedCell === mol.id ? 1.0 : 0.85)
.animation({ duration: 200 })
.onClick(() => {
this.selectedCell = mol.id;
moleculeLightTheme.switchActivityLight(mol.activityLevel);
AppStorage.setOrCreate('selectedMoleculeId', mol.id);
})
}
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.padding(12)
.layoutWeight(1)
// 图例
Row() {
Text('高活性').fontSize(10).fontColor('#27AE60')
Row().width(40).height(8).backgroundColor('linear-gradient(to right, #27AE60, #E74C3C)').borderRadius(4).margin({ left: 4, right: 4 })
Text('毒性').fontSize(10).fontColor('#E74C3C')
}
.width('100%')
.height(32)
.justifyContent(FlexAlign.Center)
.borderTop({ width: 0.5, color: '#EEEEEE' })
}
.width('100%').height('100%')
.backgroundColor('rgba(255, 255, 255, 0.9)')
.backdropFilter($r('sys.blur.20'))
.borderRadius(16)
.shadow({ radius: 24, color: 'rgba(0, 0, 0, 0.15)', offsetX: 0, offsetY: 8 })
.opacity(this.isWindowFocused ? 1.0 : 0.65)
.animation({ duration: 300, curve: Curve.EaseInOut })
}
}
四、关键技术总结
4.1 HMAF药物研发开发清单
| 技术点 | API/方法 | 应用场景 |
|---|---|---|
| 多智能体会话 | hmaf.createAgentSession({ mode: MULTI_AGENT }) |
四层Agent协作研发 |
| 意图解析 | intents.createIntentEngine({ supportedDomains }) |
研发意图理解 |
| 靶点预测Agent | AgentType.TARGET_PREDICTOR |
基因组/蛋白质组分析 |
| 分子生成Agent | AgentType.MOLECULE_GENERATOR |
AI扩散模型生成分子 |
| 活性评估Agent | AgentType.ACTIVITY_ASSESSOR |
ADMET综合评估 |
| 临床设计Agent | AgentType.TRIAL_DESIGNER |
试验方案优化 |
4.2 分子活性光效映射
| 活性等级 | 主色调 | 脉冲速度 | 典型场景 |
|---|---|---|---|
| 高活性 | #27AE60 翠绿 |
4000ms | IC50 < 10nM |
| 中活性 | #3498DB 淡蓝 |
3500ms | IC50 10-100nM |
| 低活性 | #F39C12 暖黄 |
2500ms | IC50 100-1000nM |
| 无活性 | #95A5A6 灰白 |
3000ms | IC50 > 1000nM |
| 毒性预警 | #E74C3C 危险红 |
1000ms | hERG > 30% |
4.3 靶点类型光效标识
| 靶点类型 | 光晕色 | 标识意义 |
|---|---|---|
| 激酶 | #9B59B6 蓝紫 |
磷酸化信号 |
| GPCR | #E67E22 橙红 |
跨膜信号 |
| 离子通道 | #1ABC9C 青绿 |
离子通透 |
| 核受体 | #F1C40F 金黄 |
基因调控 |
| 蛋白酶 | #E74C3C 深红 |
催化切割 |
五、运行效果展示
5.1 靶点发现阶段 - 高活性光效
预测EGFR靶点成药性85%,界面呈现翠绿色光效:靶点信息卡片翠绿光晕,底部导航脉冲缓慢,传递"靶点优秀、可继续推进"的直觉。
5.2 分子生成阶段 - 中活性光效
生成分子IC50=50nM,界面切换为淡蓝色光效:分子列表中该分子淡蓝边框标识,活性热力图对应单元格淡蓝色,提示"有活性、需进一步优化"。
5.3 活性评估阶段 - 毒性预警光效
检测到某分子hERG抑制45%,界面切换为危险红色光效:急促脉冲(1秒周期)配合顶部警示光条,该分子在列表中红色高亮,强烈提示"心脏毒性风险、终止开发"。
六、总结与展望
本文基于HarmonyOS 6(API 23)的悬浮导航 、沉浸光感 与HMAF智能体框架特性,完整实战了一款面向PC端的"药界智脑"AI智能体药物研发与分子模拟工作台。核心创新点:
-
HMAF四层研发智能体:靶点预测Agent(基因组/蛋白质组分析)、分子生成Agent(AI扩散模型)、活性评估Agent(ADMET综合评估)、临床设计Agent(试验方案优化),实现"靶点发现→分子生成→活性评估→临床设计"的全链路自动化
-
分子活性光效系统:五种活性等级拥有专属光效人格(高活性翠绿→中活性淡蓝→低活性暖黄→无活性灰白→毒性预警危险红),实现药物化学家"一眼感知分子潜力"
-
悬浮研发导航:底部悬浮页签承载"靶点发现-分子生成-活性评估-临床设计"四个研发阶段,实时显示活性统计徽章
-
PC级多窗口协作研发 :主分子编辑器 + 浮动3D分子视窗 + 浮动活性热力图 + 浮动通路网络的四层架构,通过
AppStorage实现跨窗口光效同步 -
研发意图沉浸感知:通过Intents Kit解析药物化学家意图,自动触发对应Agent协作并调整界面活性光效
未来扩展方向:
- 分布式药物研发:PC主控研发+服务器集群分子动力学模拟+平板实验记录的三端流转
- 实时活性预测:接入实验室自动化平台,合成后立即测试并更新活性光效
- AI辅助专利规避:智能体自动分析专利布局,生成规避专利的新颖分子
- 虚拟临床试验:基于数字孪生技术,在虚拟患者群体中预测试验结果
转载自:https://blog.csdn.net/u014727709/article/details/161594148
欢迎 👍点赞✍评论⭐收藏,欢迎指正