当前位置: 首页 > news >正文

【2026最新】鸿蒙NEXT培训班管理系统实战:从零搭建完整项目架构

引言

想用鸿蒙NEXT开发一个完整的培训班管理系统,却不知道从何下手?项目结构混乱、模块划分不清晰、代码难以维护?别担心,本文将手把手带你从零搭建一个高内聚低耦合的鸿蒙NEXT项目架构,涵盖需求分析、架构设计、目录规划、环境搭建和基础框架实现,让你的培训班管理系统开发事半功倍!


一、需求分析

1.1 业务背景

培训班管理系统是一个典型的教育类应用,主要用于管理培训机构的日常运营,包括学员管理、课程管理、报名管理、考勤管理等核心功能。

1.2 功能需求

核心功能模块

模块

功能点

优先级

学员管理

学员信息录入、查询、修改、删除

P0

课程管理

课程信息维护、课程表展示

P0

报名管理

学员报名、退费、课程选择

P0

考勤管理

签到签退、考勤统计

P1

数据统计

学员统计、课程统计、收入统计

P1

用户角色
  • 管理员:系统管理、数据统计、权限管理

  • 教师:课程管理、考勤管理、学员查看

  • 学员:课程查看、报名、个人信息管理

1.3 界面原型

┌─────────────────────────────────────┐ │ 首页 (TabBar) │ ├─────────────────────────────────────┤ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ 学员 │ │ 课程 │ │ 报名 │ │ 我的 │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ └─────────────────────────────────────┘

二、架构设计

2.1 整体架构

采用分层架构设计,将应用分为以下层次:

┌─────────────────────────────────────┐ │ UI层 (ArkUI) │ ├─────────────────────────────────────┤ │ ViewModel层 │ ├─────────────────────────────────────┤ │ Service层 │ ├─────────────────────────────────────┤ │ Data层 │ └─────────────────────────────────────┘

2.2 技术选型

技术领域

技术方案

说明

UI框架

ArkUI

鸿蒙原生UI框架

状态管理

@State/@Prop/@Link

组件状态管理

数据持久化

Preferences + RDB

轻量级+关系型数据库

网络请求

@ohos.net.http

系统HTTP API

路由管理

Navigation + NavRouter

页面导航

2.3 模块划分

TrainingManagement/ ├── entry/ # 主模块 │ ├── src/main/ets/ │ │ ├── pages/ # 页面 │ │ ├── components/ # 公共组件 │ │ ├── viewmodel/ # 视图模型 │ │ ├── service/ # 业务服务 │ │ ├── model/ # 数据模型 │ │ ├── common/ # 公共工具 │ │ └── resources/ # 资源文件 │ └── src/main/resources/ # 系统资源 └── features/ # 功能模块 ├── student/ # 学员模块 ├── course/ # 课程模块 ├── enrollment/ # 报名模块 └── attendance/ # 考勤模块

三、目录结构规划

3.1 完整目录结构

entry/src/main/ets/ ├── pages/ │ ├── Index.ets # 首页 │ ├── StudentList.ets # 学员列表页 │ ├── StudentDetail.ets # 学员详情页 │ ├── CourseList.ets # 课程列表页 │ ├── CourseDetail.ets # 课程详情页 │ ├── EnrollmentPage.ets # 报名页面 │ └── MyPage.ets # 个人中心 ├── components/ │ ├── common/ │ │ ├── TitleBar.ets # 标题栏 │ │ ├── SearchBar.ets # 搜索栏 │ │ ├── EmptyView.ets # 空状态视图 │ │ └── LoadingView.ets # 加载视图 │ ├── student/ │ │ ├── StudentCard.ets # 学员卡片 │ │ └── StudentForm.ets # 学员表单 │ └── course/ │ ├── CourseCard.ets # 课程卡片 │ └── CourseSchedule.ets # 课程表 ├── viewmodel/ │ ├── StudentViewModel.ets # 学员视图模型 │ ├── CourseViewModel.ets # 课程视图模型 │ └── EnrollmentViewModel.ets # 报名视图模型 ├── service/ │ ├── StudentService.ets # 学员服务 │ ├── CourseService.ets # 课程服务 │ └── EnrollmentService.ets # 报名服务 ├── model/ │ ├── Student.ets # 学员模型 │ ├── Course.ets # 课程模型 │ └── Enrollment.ets # 报名模型 ├── common/ │ ├── Constants.ets # 常量定义 │ ├── Utils.ets # 工具类 │ └── DatabaseHelper.ets # 数据库帮助类 └── resources/ ├── base/element/ # 元素资源 ├── base/media/ # 媒体资源 └── base/profile/ # 配置文件

3.2 模块职责说明

目录

职责

说明

pages

页面层

负责UI展示和用户交互

components

组件层

可复用的UI组件

viewmodel

视图模型层

管理页面状态和业务逻辑

service

服务层

处理业务逻辑和数据操作

model

模型层

定义数据结构

common

公共层

工具类和常量定义


四、开发环境搭建

4.1 DevEco Studio安装

  1. 下载DevEco Studio

    • 访问华为开发者联盟官网

    • 下载最新版本DevEco Studio 5.0+

  2. 安装配置

    系统要求: - Windows 10/11 64位 - 内存:16GB以上 - 硬盘:100GB以上可用空间
  3. SDK配置

    • 打开DevEco Studio

    • 进入Settings → HarmonyOS SDK

    • 下载API 12及以上版本

4.2 项目创建

  1. 创建新项目

    • 打开DevEco Studio

    • 选择"Create HarmonyOS Project"

    • 选择"Empty Ability"模板

    • 配置项目信息:

      • Project Name: TrainingManagement

      • Bundle Name: com.example.training

      • Compile SDK: API 12

      • Model: Stage

  2. 项目初始化

    # 项目结构生成后,检查以下文件 - entry/src/main/ets/entryability/EntryAbility.ets - entry/src/main/ets/pages/Index.ets - entry/src/main/module.json5

4.3 开发工具配置

  1. 代码风格配置

    // .eslintrc.json { "extends": "@typescript-eslint/recommended", "rules": { "indent": ["error", 2], "quotes": ["error", "single"], "semi": ["error", "always"] } }
  2. Git配置

    # 初始化Git仓库 git init git add . git commit -m "初始化鸿蒙培训班管理系统项目"

五、基础框架代码实现

5.1 数据模型定义

// model/Student.ets export interface Student { id: string; name: string; phone: string; email: string; gender: number; // 0: 未知, 1: 男, 2: 女 birthday: string; address: string; avatar: string; createTime: string; updateTime: string; }
// model/Course.ets export interface Course { id: string; name: string; description: string; teacher: string; price: number; duration: number; // 课时 maxStudents: number; currentStudents: number; startTime: string; endTime: string; status: number; // 0: 未开始, 1: 进行中, 2: 已结束 createTime: string; updateTime: string; }
// model/Enrollment.ets export interface Enrollment { id: string; studentId: string; courseId: string; enrollTime: string; status: number; // 0: 已报名, 1: 已上课, 2: 已退费 remark: string; createTime: string; updateTime: string; }

5.2 数据库帮助类

// common/DatabaseHelper.ets import rdb from '@ohos.data.relationalStore'; const DB_NAME = 'training_management.db'; const DB_VERSION = 1; export class DatabaseHelper { private static instance: DatabaseHelper; private rdbStore: rdb.RdbStore | null = null; private constructor() {} static getInstance(): DatabaseHelper { if (!DatabaseHelper.instance) { DatabaseHelper.instance = new DatabaseHelper(); } return DatabaseHelper.instance; } async init(context: Context): Promise<void> { const config: rdb.StoreConfig = { name: DB_NAME, securityLevel: rdb.SecurityLevel.S1 }; this.rdbStore = await rdb.getRdbStore(context, config, DB_VERSION); await this.createTables(); } private async createTables(): Promise<void> { const createStudentTable = ` CREATE TABLE IF NOT EXISTS student ( id TEXT PRIMARY KEY, name TEXT NOT NULL, phone TEXT, email TEXT, gender INTEGER DEFAULT 0, birthday TEXT, address TEXT, avatar TEXT, create_time TEXT, update_time TEXT ) `; const createCourseTable = ` CREATE TABLE IF NOT EXISTS course ( id TEXT PRIMARY KEY, name TEXT NOT NULL, description TEXT, teacher TEXT, price REAL, duration INTEGER, max_students INTEGER, current_students INTEGER DEFAULT 0, start_time TEXT, end_time TEXT, status INTEGER DEFAULT 0, create_time TEXT, update_time TEXT ) `; const createEnrollmentTable = ` CREATE TABLE IF NOT EXISTS enrollment ( id TEXT PRIMARY KEY, student_id TEXT NOT NULL, course_id TEXT NOT NULL, enroll_time TEXT, status INTEGER DEFAULT 0, remark TEXT, create_time TEXT, update_time TEXT, FOREIGN KEY (student_id) REFERENCES student(id), FOREIGN KEY (course_id) REFERENCES course(id) ) `; await this.rdbStore?.executeSql(createStudentTable); await this.rdbStore?.executeSql(createCourseTable); await this.rdbStore?.executeSql(createEnrollmentTable); } getRdbStore(): rdb.RdbStore | null { return this.rdbStore; } }

5.3 工具类

// common/Utils.ets export class Utils { /** * 生成唯一ID */ static generateId(): string { return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } /** * 格式化日期 */ static formatDate(date: Date, format: string = 'YYYY-MM-DD HH:mm:ss'): string { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hours = String(date.getHours()).padStart(2, '0'); const minutes = String(date.getMinutes()).padStart(2, '0'); const seconds = String(date.getSeconds()).padStart(2, '0'); return format .replace('YYYY', String(year)) .replace('MM', month) .replace('DD', day) .replace('HH', hours) .replace('mm', minutes) .replace('ss', seconds); } /** * 验证手机号 */ static isValidPhone(phone: string): boolean { const phoneRegex = /^1[3-9]\d{9}$/; return phoneRegex.test(phone); } /** * 验证邮箱 */ static isValidEmail(email: string): boolean { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); } /** * 显示提示信息 */ static showToast(message: string): void { // 使用系统Toast API console.info(message); } }

5.4 常量定义

// common/Constants.ets export class Constants { // 数据库版本 static readonly DB_VERSION = 1; // 性别常量 static readonly GENDER_UNKNOWN = 0; static readonly GENDER_MALE = 1; static readonly GENDER_FEMALE = 2; // 课程状态 static readonly COURSE_STATUS_NOT_STARTED = 0; static readonly COURSE_STATUS_IN_PROGRESS = 1; static readonly COURSE_STATUS_ENDED = 2; // 报名状态 static readonly ENROLLMENT_STATUS_ENROLLED = 0; static readonly ENROLLMENT_STATUS_ATTENDED = 1; static readonly ENROLLMENT_STATUS_REFUNDED = 2; // 页面路由 static readonly PAGE_INDEX = 'pages/Index'; static readonly PAGE_STUDENT_LIST = 'pages/StudentList'; static readonly PAGE_STUDENT_DETAIL = 'pages/StudentDetail'; static readonly PAGE_COURSE_LIST = 'pages/CourseList'; static readonly PAGE_COURSE_DETAIL = 'pages/CourseDetail'; static readonly PAGE_ENROLLMENT = 'pages/EnrollmentPage'; static readonly PAGE_MY = 'pages/MyPage'; }

5.5 首页实现

// pages/Index.ets import { Constants } from '../common/Constants'; @Entry @Component struct Index { @State currentIndex: number = 0; private tabItems: TabBarItem[] = [ { title: '学员', icon: $r('app.media.ic_student') }, { title: '课程', icon: $r('app.media.ic_course') }, { title: '报名', icon: $r('app.media.ic_enrollment') }, { title: '我的', icon: $r('app.media.ic_my') } ]; build() { Column() { // 标题栏 TitleBar({ title: '培训班管理系统' }) // 内容区域 Tabs({ barPosition: BarPosition.End }) { TabContent() { StudentList() } .tabBar(this.TabBarItem(0)) TabContent() { CourseList() } .tabBar(this.TabBarItem(1)) TabContent() { EnrollmentPage() } .tabBar(this.TabBarItem(2)) TabContent() { MyPage() } .tabBar(this.TabBarItem(3)) } .onChange((index: number) => { this.currentIndex = index; }) } .width('100%') .height('100%') .backgroundColor('#F5F5F5') } @Builder TabBarItem(index: number) { Column() { Image(this.tabItems[index].icon) .width(24) .height(24) .fillColor(this.currentIndex === index ? '#007DFF' : '#999999') Text(this.tabItems[index].title) .fontSize(12) .fontColor(this.currentIndex === index ? '#007DFF' : '#999999') .margin({ top: 4 }) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } } interface TabBarItem { title: string; icon: Resource; }

5.6 标题栏组件

// components/common/TitleBar.ets @Component export struct TitleBar { @Prop title: string = ''; @Prop showBack: boolean = false; backCallback: () => void = () => {}; build() { Row() { // 返回按钮 if (this.showBack) { Image($r('app.media.ic_back')) .width(24) .height(24) .onClick(() => { this.backCallback(); }) } // 标题 Text(this.title) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#333333') .layoutWeight(1) .textAlign(TextAlign.Center) } .width('100%') .height(56) .padding({ left: 16, right: 16 }) .backgroundColor('#FFFFFF') } }

六、踩坑记录

6.1 数据库初始化问题

问题:数据库初始化时,表创建失败。

原因:SQL语句中的外键约束导致创建失败。

解决方案

// 先创建主表,再创建外键表 await this.rdbStore?.executeSql(createStudentTable); await this.rdbStore?.executeSql(createCourseTable); await this.rdbStore?.executeSql(createEnrollmentTable);

6.2 资源引用问题

问题:图片资源无法加载。

原因:资源路径配置错误。

解决方案

// 确保资源文件放在正确的目录 entry/src/main/resources/base/media/

6.3 组件通信问题

问题:父子组件数据不同步。

原因:@Prop装饰器是单向数据流。

解决方案

// 使用@Link实现双向数据绑定 @Link isRefresh: boolean;

七、总结与预告

本文要点回顾

  1. 需求分析:明确了培训班管理系统的功能需求和用户角色

  2. 架构设计:采用分层架构,分离UI、业务逻辑和数据层

  3. 目录规划:按照功能模块划分,提高代码可维护性

  4. 环境搭建:详细介绍了DevEco Studio的安装和配置

  5. 基础框架:实现了数据模型、数据库、工具类等基础代码

下期预告

下期我们将深入讲解UI界面篇,包括:

  • 学员列表页面实现

  • 课程详情页面设计

  • 报名页面交互优化

  • 响应式布局适配

互动引导

如果本文对你有帮助,请点赞、收藏、关注!有任何问题欢迎在评论区留言,我会及时回复。


系列文章导航

  • 第1篇:项目架构篇(本文)

  • 第2篇:UI界面篇

  • 第3篇:状态管理篇

  • 第4篇:数据持久化篇

  • 第5篇:性能优化篇

http://www.jsqmd.com/news/833400/

相关文章:

  • 嵌入式软件架构模式实战解析:从前后台到RTOS的选型指南
  • 3步搞定百度网盘高速下载:无需会员的终极提速指南
  • 终极显卡调校指南:如何用NVIDIA Profile Inspector释放游戏性能
  • SAS横向合并:从DATA步MERGE到PROC SQL JOIN的深度对比与应用
  • 开源AI应用构建平台Databerry:自托管RAG方案部署与调优指南
  • 机器人抓取新范式:基于经验记忆库的智能抓取系统设计与实现
  • 项目——基于C/S架构的文件传输系统平台 (1)——重构
  • Windows 11安卓子系统终极指南:开启跨平台应用新时代
  • AssetStudio深度解析:从游戏资源提取到创意开发的完整指南
  • CircuitPython入门:从GPIO到NeoPixel的嵌入式开发实践
  • 开放CLI架构解析:从命令行到智能交互中心的演进之路
  • Go语言静态站点生成器Zeuxis:极简架构与高性能构建实践
  • JetBrains IDE试用期重置终极指南:3种简单方法实现30天无限续杯
  • 如何免费高效优化电脑性能:UXTU终极调优指南
  • AI智能体综合能力评估平台AgentBench:从原理到实战的完整指南
  • QtScrcpy:免费开源的Android投屏控制终极指南,3个核心功能让你轻松上手
  • 智慧课堂后端架构解析:微服务、实时通信与性能优化实战
  • 基于FLORA与FONA的可穿戴设备蜂窝通信实战指南
  • 从开源AI导师项目GURU-Ai拆解:如何构建具备教学能力的智能体
  • 量子计算噪声控制:SCQC方法与动态校正门技术
  • 解锁NVIDIA显卡隐藏性能:Profile Inspector终极调校指南
  • Mantic.sh:Bash脚本实现的终端命令自动化与效率提升工具
  • 量子私有信息检索(QPIR)技术解析与应用前景
  • RePKG:解锁Wallpaper Engine资源的专业工具指南
  • Code Container:开箱即用的容器化开发环境实战指南
  • LinuxACL权限模型稳定性治理方法
  • 基于AutoHotkey的Windows桌面自动化工具开发实战
  • 5分钟彻底掌控Windows右键菜单:ContextMenuManager新手完全指南
  • NVIDIA Profile Inspector:解锁显卡隐藏性能的终极调校指南
  • 如何查看windows端口占用情况,禁止Win11系统自动更新工具