HarmonyOS NEXT AI 智能生活助手:创建企业级 AI 工程与目录结构

HarmonyOS NEXT AI 智能生活助手:创建企业级 AI 工程与目录结构

前言

在上一篇 项目规划与架构设计 中,我们详细介绍了 HarmonyAI 的整体架构和 30 篇博客规划。本文是系列的第 02 篇 ,将带领大家从零开始创建一个企业级的 HarmonyOS NEXT AI 工程。

企业级工程 不是简单的新建项目,而是按照生产级标准搭建项目骨架,包括目录结构、模块划分、依赖管理、代码规范等。好的工程结构是后续 28 篇博客的基础。

本文将涵盖:

  1. 两阶段创建流程:先创建基础工程,再搭建企业级目录结构
  2. 完整目录树:18+ 个模块目录设计
  3. 核心配置:build-profile.json5、oh-package.json5、hvigorfile.ts
  4. 首个页面:验证项目可编译运行
  5. Git 初始化:版本控制与 Tag 管理

图1:HarmonyAI 企业级目录结构树

一、创建基础工程

1.1 环境准备

在开始之前,请确保已安装以下开发环境:

工具 版本要求 说明
DevEco Studio 5.0+ HarmonyOS NEXT 官方 IDE
HarmonyOS SDK 5.0.0+ API 12+
Node.js 18+ 用于 hvigor 构建
Git 2.30+ 版本控制

1.2 使用 DevEco Studio 创建基础工程

打开 DevEco Studio,按以下步骤操作:

  1. 点击 Create Project
  2. 选择 Empty Ability 模板
  3. 配置项目信息:
配置项 说明
Project Name HarmonyAI 项目名称
Bundle Name com.harmonyai.app 应用包名
Save Location 自定义路径 建议不含中文字符
Compatible API 12+ API 版本
Model Stage 应用模型
Language ArkTS 开发语言
Device Type Phone 目标设备

1.3 创建完成后生成的目录

DevEco Studio 默认生成的项目结构如下:

text 复制代码
HarmonyAI/
├── AppScope/
│   ├── app.json5             # 应用配置
│   └── resources/            # 应用级资源
├── entry/
│   ├── src/
│   │   ├── main/
│   │   │   ├── ets/
│   │   │   │   ├── entryability/
│   │   │   │   │   └── EntryAbility.ts
│   │   │   │   └── pages/
│   │   │   │       └── Index.ets
│   │   │   └── resources/
│   │   └── module.json5
│   ├── build-profile.json5   # HAP 构建配置
│   └── oh-package.json5      # 依赖配置
├── hvigor/
│   └── hvigor-config.json5
├── hvigorfile.ts             # Hvigor 构建入口
├── oh-package.json5          # 顶层依赖配置
├── build-profile.json5       # 顶层构建配置
└── local.properties          # 本地 SDK 路径

二、搭建企业级目录结构

2.1 设计思路

企业级目录结构遵循以下原则:

  1. 按功能模块划分:每个目录有明确的职责
  2. 高内聚低耦合:模块间通过接口通信
  3. 可扩展性:新增功能不需要改动现有目录
  4. 领域驱动:按业务领域组织代码

根据 Project-Design.md 的规划,我们需要在 entry/src/main/ets/ 下新增以下目录:

2.2 完整目录树

text 复制代码
ets/
├── entryability/
│   └── EntryAbility.ts       # Ability 入口
├── pages/                    # 页面目录(12-15 个页面)
│   ├── SplashPage.ets        # 启动页
│   ├── HomePage.ets          # 首页
│   ├── ChatPage.ets          # AI 聊天页
│   ├── OCRPage.ets           # OCR 识别页
│   ├── TranslatePage.ets     # 翻译页
│   ├── FlowerPage.ets        # 每日花语页
│   ├── SummaryPage.ets       # 文章总结页
│   ├── CodePage.ets          # 代码解释页
│   ├── TodoPage.ets          # 待办生成页
│   ├── SchedulePage.ets      # 日程规划页
│   ├── SettingPage.ets       # 设置页
│   └── AboutPage.ets         # 关于页
├── components/               # 公共组件
│   ├── ChatBubble.ets        # 聊天气泡
│   ├── MarkdownView.ets      # Markdown 渲染
│   ├── TypingView.ets        # 打字机效果
│   ├── PromptCard.ets        # Prompt 卡片
│   ├── AIAvatar.ets          # AI 头像
│   ├── MessageItem.ets       # 消息列表项
│   ├── InputBar.ets          # 输入栏
│   ├── ModelSelector.ets     # 模型选择器
│   ├── LoadingView.ets       # 加载动画
│   ├── HistoryCard.ets       # 历史卡片
│   ├── CodeBlock.ets         # 代码块
│   ├── Toolbar.ets           # 工具栏
│   ├── ImagePicker.ets       # 图片选择器
│   ├── OCRCard.ets           # OCR 结果卡片
│   └── SettingItem.ets       # 设置项
├── common/                   # 公共模块
│   ├── Logger.ts             # 日志工具
│   ├── Constants.ts          # 全局常量
│   └── Types.ts              # 全局类型定义
├── repository/               # 数据仓库层
│   ├── ChatRepository.ts     # 聊天数据仓库
│   ├── ConversationRepository.ts # 会话仓库
│   ├── PromptRepository.ts   # Prompt 仓库
│   └── SettingsRepository.ts # 设置仓库
├── service/                  # 服务层
│   └── AIService.ts          # AI 服务统一入口
├── provider/                 # LLM Provider
│   ├── LLMProvider.ts        # Provider 接口
│   ├── OpenAIProvider.ts     # OpenAI
│   ├── DeepSeekProvider.ts   # DeepSeek
│   ├── QwenProvider.ts       # 通义千问
│   ├── ZhipuProvider.ts      # 智谱 AI
│   └── DoubaoProvider.ts     # 豆包
├── ai/                       # AI 能力模块
│   ├── ChatManager.ts        # 聊天管理
│   ├── TranslateManager.ts   # 翻译管理
│   ├── OCRManager.ts         # OCR 管理
│   ├── SummaryManager.ts     # 总结管理
│   ├── FlowerManager.ts      # 花语管理
│   ├── TodoManager.ts        # 待办管理
│   ├── ScheduleManager.ts    # 日程管理
│   └── CodeManager.ts        # 代码解释管理
├── prompt/                   # Prompt 管理
│   ├── PromptManager.ts      # Prompt 管理器
│   └── templates/            # Prompt 模板文件
│       ├── chat.md
│       ├── translate.md
│       ├── flower.md
│       ├── summary.md
│       ├── todo.md
│       ├── schedule.md
│       ├── code.md
│       └── system.md
├── model/                    # 数据模型
│   ├── ChatMessage.ts        # 聊天消息
│   ├── Conversation.ts       # 会话
│   ├── Prompt.ts             # Prompt
│   ├── ModelConfig.ts        # 模型配置
│   └── AIResponse.ts         # AI 响应
├── database/                 # 数据库
│   ├── DatabaseManager.ts    # 数据库管理器
│   └── tables/               # 表定义
├── theme/                    # 主题管理
│   ├── ThemeManager.ts       # 主题管理器
│   ├── LightTheme.ts         # 浅色主题
│   └── DarkTheme.ts          # 深色主题
├── constants/                # 常量
│   ├── AppConstants.ts       # 应用常量
│   └── ApiConstants.ts       # API 常量
└── utils/                    # 工具类
    ├── AIUtil.ts             # AI 工具
    ├── MarkdownUtil.ts       # Markdown 工具
    ├── PromptUtil.ts         # Prompt 工具
    ├── JsonUtil.ts           # JSON 工具
    ├── ImageUtil.ts          # 图片工具
    ├── OCRUtil.ts            # OCR 工具
    ├── RouterUtil.ts         # 路由工具
    ├── ToastUtil.ts          # Toast 工具
    ├── ThemeUtil.ts          # 主题工具
    └── PreferenceUtil.ts     # 偏好存储工具

完整的目录结构包含 18 个一级目录30+ 个页面和组件10+ 工具类,覆盖了企业级 AI 应用的所有模块。


三、核心配置文件

3.1 build-profile.json5(顶层)

json5 复制代码
{
  "app": {
    "products": [
      {
        "name": "default",
        "signingConfig": "default"
      }
    ],
    "buildSettings": {
      "compatibleSdkVersion": "5.0.0",
      "compileSdkVersion": "5.0.0",
      "targetSdkVersion": "5.0.0"
    }
  },
  "modules": [
    {
      "name": "entry",
      "srcPath": "./entry",
      "buildProfile": "./entry/build-profile.json5"
    }
  ]
}

3.2 module.json5(Entry 模块)

json5 复制代码
{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "HarmonyAI 主模块",
    "mainAbility": "EntryAbility",
    "deviceTypes": ["phone"],
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ts",
        "description": "应用主入口",
        "icon": "$media:app_icon",
        "label": "$string:app_name",
        "startWindowIcon": "$media:app_icon",
        "startWindowBackground": "$color:start_window_background"
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.READ_MEDIA"
      },
      {
        "name": "ohos.permission.CAMERA"
      }
    ]
  }
}

注意INTERNET 权限用于 AI API 调用,READ_MEDIACAMERA 用于 OCR 图片识别功能。

3.3 oh-package.json5(Entry 模块)

json5 复制代码
{
  "name": "entry",
  "version": "1.0.0",
  "description": "HarmonyAI entry module",
  "dependencies": {
    "@ohos/axios": "^2.2.0",
    "@ohos/data-preferences": "^1.0.0",
    "@ohos/data.persistence": "^1.0.0",
    "@ohos.multimedia.image": "^1.0.0",
    "@ohos.multimedia.camera": "^1.0.0",
    "@kit.MediaLibraryKit": "^1.0.0"
  }
}

四、创建首个验证页面

4.1 EntryAbility 入口

typescript 复制代码
// entryability/EntryAbility.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import display from '@ohos.display';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    hilog.info(0x0000, 'HarmonyAI', 'Ability onCreate');
  }

  onDestroy() {
    hilog.info(0x0000, 'HarmonyAI', 'Ability onDestroy');
  }

  async onWindowStageCreate(windowStage: window.WindowStage) {
    hilog.info(0x0000, 'HarmonyAI', 'onWindowStageCreate');

    // 安全区处理:获取状态栏和导航栏高度并转换为 vp
    await this.initSafeArea();

    windowStage.loadContent('pages/SplashPage', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'HarmonyAI', 'Failed to load content. Cause: %{public}s',
          JSON.stringify(err));
        return;
      }
      hilog.info(0x0000, 'HarmonyAI', 'Succeeded in loading content');
    });
  }

  // 初始化安全区高度
  private async initSafeArea(): Promise<void> {
    try {
      const defaultDisplay = display.getDefaultDisplaySync();
      const densityPixels = defaultDisplay.densityPixels;

      // 获取窗口实例
      const windowClass = await window.getLastWindow(this.context);

      // 获取状态栏高度(px 转 vp)
      const statusBarHeightPx = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height;
      const statusBarHeight = statusBarHeightPx / densityPixels;

      // 获取导航栏高度(px 转 vp)
      const navBarHeightPx = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height;
      const navBarHeight = navBarHeightPx / densityPixels;

      // 存储到 AppStorage,供所有页面共享
      AppStorage.setOrCreate<number>('statusBarHeight', statusBarHeight);
      AppStorage.setOrCreate<number>('navBarHeight', navBarHeight);

      hilog.info(0x0000, 'HarmonyAI',
        'SafeArea statusBar: %{public}.2f vp, navBar: %{public}.2f vp',
        statusBarHeight, navBarHeight);
    } catch (error) {
      hilog.error(0x0000, 'HarmonyAI',
        'Failed to init safe area: %{public}s', error.message);
      // 使用默认值兜底
      AppStorage.setOrCreate<number>('statusBarHeight', 32);
      AppStorage.setOrCreate<number>('navBarHeight', 24);
    }
  }

  onWindowStageDestroy() {
    hilog.info(0x0000, 'HarmonyAI', 'onWindowStageDestroy');
  }

  onForeground() {
    hilog.info(0x0000, 'HarmonyAI', 'onForeground');
  }

  onBackground() {
    hilog.info(0x0000, 'HarmonyAI', 'onBackground');
  }
}

4.2 启动页(SplashPage)

typescript 复制代码
// pages/SplashPage.ets
@Entry
@Component
struct SplashPage {
  @State opacityValue: number = 0;
  @State scaleValue: number = 0.8;

  aboutToAppear() {
    // 启动动画
    animateTo({ duration: 1000, curve: Curve.FastOutSlowIn }, () => {
      this.opacityValue = 1;
      this.scaleValue = 1;
    });

    // 延迟跳转首页
    setTimeout(() => {
      RouterUtil.navigateTo('pages/HomePage');
    }, 2000);
  }

  build() {
    Column() {
      // Logo
      Image($r('app.media.app_icon'))
        .width(120)
        .height(120)
        .opacity(this.opacityValue)
        .scale({ x: this.scaleValue, y: this.scaleValue })
      // 应用名称
      Text($r('app.string.app_name'))
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 24 })
        .opacity(this.opacityValue)
      // 应用描述
      Text('AI 智能生活助手')
        .fontSize(16)
        .fontColor(Color.Gray)
        .margin({ top: 8 })
        .opacity(this.opacityValue)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor($r('app.color.splash_background'));
  }
}

4.3 验证编译

在 DevEco Studio 中,执行以下验证:

bash 复制代码
# 1. 清理项目
hvigorw clean

# 2. 编译 HAP
hvigorw assembleHap

# 3. 编译成功输出
> BUILD SUCCESSFUL in 30s

出现 BUILD SUCCESSFUL 说明项目创建成功,企业级目录结构搭建完成。


五、Git 初始化

5.1 创建 .gitignore

bash 复制代码
# HarmonyOS
.idea/
.gradle/
build/
local.properties
*.hprof
*.iml

# Node
node_modules/
.hvigor/

# OS
.DS_Store
Thumbs.db

# IDE
*.swp
*.swo

5.2 初始化 Git 仓库

bash 复制代码
# 初始化仓库
git init

# 添加文件
git add .

# 首次提交
git commit -m "feat(init): 初始化企业级 AI 工程

- 创建 HarmonyOS NEXT 基础工程
- 搭建 18 个模块的企业级目录结构
- 配置 build-profile.json5、module.json5
- 实现启动页与基本动画
- 配置 Git 版本管理

Co-Authored-By: AtomCode (deepseek-v4-flash) <noreply@atomgit.com>"

# 创建 Tag
git tag v0.0.1

六、验证清单

6.1 项目结构完整性检查

检查项 要求 状态
一级目录 18 个
页面文件 12 个
组件文件 15 个
工具类 10 个
Provider 5 个
Prompt 模板 8 个
数据模型 5 个
配置文件 3 个

6.2 编译运行检查

  1. DevEco Studio 打开项目无错误
  2. hvigorw assembleHap 编译成功
  3. 启动页 动画正常显示
  4. 路由跳转 到首页正常

如果以上检查项全部通过,说明企业级工程创建成功!


七、企业级目录结构最佳实践

7.1 分层依赖规则

各层的依赖关系必须遵循以下规则:

text 复制代码
pages/ → components/ → common/
pages/ → repository/ → service/ → provider/
service/ → ai/ → prompt/
repository/ → database/
components/ → theme/ → constants/

禁止 页面层直接调用 Provider 或 PromptManager,必须通过 AIService 统一封装。

7.2 模块职责矩阵

模块 对外暴露 内部依赖 禁止依赖
pages 页面组件 components, repository provider, ai
components UI 组件 theme, constants repository, service
repository 数据接口 database, model pages, components
service AI 服务 provider, ai, prompt pages, components
provider LLM 接口 constants 业务层
prompt Prompt 模板
model 类型定义

7.3 命名规范

typescript 复制代码
// 1. 文件命名:大驼峰
// 正确:ChatPage.ets, AIService.ts
// 错误:chatPage.ets, ai_service.ts

// 2. 类/接口命名:大驼峰
interface ChatMessage {}
class AIService {}

// 3. 方法命名:小驼峰
sendMessage()
loadPrompts()

// 4. 常量命名:全大写 + 下划线
const API_BASE_URL = 'https://api.example.com'
const MAX_RETRY_COUNT = 3

7.4 HarmonyOS NEXT 开发关键注意事项

在企业级 HarmonyOS NEXT 开发中,以下细节直接影响应用的稳定性和用户体验:

1. 安全区适配

所有页面必须通过 AppStorage 获取安全区高度,避免内容被状态栏或导航栏遮挡:

typescript 复制代码
// pages/AnyPage.ets
@Entry
@Component
struct AnyPage {
  // 从 AppStorage 读取安全区高度
  @StorageLink('statusBarHeight') statusBarHeight: number = 32;
  @StorageLink('navBarHeight') navBarHeight: number = 24;

  build() {
    Column() {
      // 顶部占位,避开状态栏
      Row().width('100%').height(this.statusBarHeight);

      // 页面内容...

      // 底部占位,避开导航栏
      Row().width('100%').height(this.navBarHeight);
    }
    .width('100%')
    .height('100%');
  }
}

2. SVG 矢量图标

HarmonyOS NEXT 设备上,emoji 会渲染为蓝色或紫色块,必须使用 SVG 矢量图替代:

用途 错误做法 正确做法
功能图标 使用 emoji(如 🔍) 使用 SVG(如 $r('app.media.ic_search')
状态标识 使用 emoji(如 ✅) 使用 SVG(如 $r('app.media.ic_check')
装饰元素 使用 emoji(如 🌟) 使用 SVG(如 $r('app.media.ic_star')

重要 :所有图标资源应放在 resources/base/media 目录下,统一使用 Image($r('app.media.xxx')) 加载。

3. 文件操作模式

HarmonyOS NEXT 中文件打开模式使用 fs.OpenMode.READ_ONLY,注意不是 READONLY

typescript 复制代码
// 正确
const file = await fs.open(filePath, fs.OpenMode.READ_ONLY);

// 错误
const file = await fs.open(filePath, fs.OpenMode.READONLY); // 不存在此枚举

八、常见问题

8.1 编译报错:module.json5 权限不足

json5 复制代码
// 错误:缺少 INTERNET 权限
// 症状:网络请求失败,hilog 提示 "Permission denied"

// 解决方案:在 module.json5 中添加
{
  "name": "ohos.permission.INTERNET"
}

8.2 目录引用路径问题

typescript 复制代码
// 错误:使用相对路径引用
import { AIService } from '../../service/AIService'

// 正确:使用相对路径从 ets 开始
import { AIService } from '../service/AIService'

提示:HarmonyOS NEXT 的模块解析规则为:相对路径从当前文件的所在目录开始计算。


九、下一步开发计划

工程创建完成后,下一篇将进行 首页设计与开发

  1. 快捷入口网格布局
  2. 最近聊天列表
  3. AI 推荐卡片
  4. 每日一句展示
  5. 今日花语 Widget

总结

本文详细介绍了如何创建一个 企业级 的 HarmonyOS NEXT AI 工程。核心要点:

  1. 两阶段创建:基础工程 → 企业级目录结构
  2. 18 个模块目录:分层清晰,职责明确
  3. 核心配置:build-profile.json5、module.json5、oh-package.json5
  4. 首个页面验证:启动页确认项目可编译运行
  5. Git 初始化:版本控制与 Tag 管理

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


上一篇: 项目规划与架构设计

下一篇: 首页设计与快捷入口实现

相关资源:

相关推荐
2501_946736161 小时前
在线考试平台如何选型?从功能、优势与应用场景角度详解
大数据·人工智能·算法
厚皮龙1 小时前
OpenCV 版本导致 AprilTag 检测数量不同
人工智能·opencv·webpack
苦猿的大模型日记1 小时前
Day44|Agent 可观测性与调试:它没报错,但它做错了
人工智能
天辛大师1 小时前
天心大师:不确定中锚定自我,AI生活的哲学命题
人工智能·算法·决策树·机器学习·生活·启发式算法
冬奇Lab2 小时前
开源项目第174期:AirLLM — 4GB 显存跑 70B,8GB 跑 405B,3.7GB 跑 2.8 万亿参数的 Kimi K3
人工智能
雪隐2 小时前
个人电脑玩AI-15让5060 Ti给你打工——MiniMax H3 本地部署实录:一个自带录音棚的视频模型,和它的 NVFP4 瘦身奇遇
前端·人工智能·后端
数字供应链安全产品选型2 小时前
中国版 Anthropic Mythos,为何是悬镜安全?
人工智能·安全
甲维斯2 小时前
Qoder+Qwen3.8Max白嫖测试!这次真牛逼了?和K3比如何?
人工智能