HarmonyOS ArkTS 实战:实现一个校园课程表与考勤管理应用
项目效果
本文使用 HarmonyOS 和 ArkTS 实现一个校园课程表与考勤管理应用。
应用可以添加和管理课程信息,设置上课时间地点和教师,查看周课程表,记录每节课的考勤状态,并提供课程筛选、考勤统计和周视图切换等功能。
项目使用 DevEco Studio 开发,适配 API 23 及以上版本。
功能介绍
本项目实现了以下功能:
- 添加课程信息
- 填写课程名称和教师姓名
- 设置上课地点
- 选择上课星期和节次
- 设置课程周数范围
- 选择课程颜色
- 记录考勤状态(出勤/迟到/请假/缺勤)
- 按周查看课程表
- 按星期筛选课程
- 统计总课程数、出勤、迟到、请假和缺勤次数
- 删除课程
定义数据结构
首先定义课程的数据结构:
typescript
interface Course {
id: number;
name: string;
teacher: string;
location: string;
dayOfWeek: number;
startSection: number;
endSection: number;
startWeek: number;
endWeek: number;
color: string;
attendance: string;
}
字段说明如下:
id:课程的唯一编号name:课程名称teacher:授课教师location:上课地点dayOfWeek:星期几(1-7)startSection:开始节次endSection:结束节次startWeek:开始周endWeek:结束周color:课程卡片颜色attendance:考勤状态(未开始/出勤/迟到/请假/缺勤)
初始化页面状态
使用 @State 保存输入内容、当前周数、筛选条件和课程颜色:
typescript
@State private nameText: string = '';
@State private teacherText: string = '';
@State private locationText: string = '';
@State private selectedDay: number = 1;
@State private startSection: number = 1;
@State private endSection: number = 2;
@State private startWeek: number = 1;
@State private endWeek: number = 16;
@State private selectedColor: string = '#3B82F6';
@State private currentWeek: number = 1;
@State private filterDay: number = 0;
@State private nextId: number = 6;
准备一些初始数据,让应用运行后可以直接展示完整效果:
typescript
@State private courses: Course[] = [
{
id: 1,
name: '高等数学',
teacher: '王教授',
location: '教一-201',
dayOfWeek: 1,
startSection: 1,
endSection: 2,
startWeek: 1,
endWeek: 16,
color: '#3B82F6',
attendance: '出勤'
},
{
id: 2,
name: '大学英语',
teacher: '李老师',
location: '教二-305',
dayOfWeek: 2,
startSection: 3,
endSection: 4,
startWeek: 1,
endWeek: 16,
color: '#10B981',
attendance: '出勤'
},
{
id: 3,
name: '鸿蒙开发',
teacher: '张教授',
location: '信息楼-502',
dayOfWeek: 3,
startSection: 5,
endSection: 6,
startWeek: 1,
endWeek: 12,
color: '#F59E0B',
attendance: '迟到'
},
{
id: 4,
name: '计算机组成原理',
teacher: '刘教授',
location: '教三-101',
dayOfWeek: 4,
startSection: 7,
endSection: 8,
startWeek: 1,
endWeek: 16,
color: '#8B5CF6',
attendance: '未开始'
}
];
添加课程
用户填写课程信息后,可以添加新课程:
typescript
private addCourse(): void {
const name: string = this.nameText.trim();
const teacher: string = this.teacherText.trim();
const location: string = this.locationText.trim();
if (name.length === 0 || teacher.length === 0 || location.length === 0) {
return;
}
const course: Course = {
id: this.nextId,
name,
teacher,
location,
dayOfWeek: this.selectedDay,
startSection: this.startSection,
endSection: this.endSection,
startWeek: this.startWeek,
endWeek: this.endWeek,
color: this.selectedColor,
attendance: '未开始'
};
this.courses = [...this.courses, course];
this.nextId += 1;
this.nameText = '';
this.teacherText = '';
this.locationText = '';
}
新添加的课程默认考勤状态为"未开始"。
考勤状态流转
课程考勤按照以下状态管理:
未开始 -> 出勤/迟到/请假/缺勤
使用以下方法更新考勤状态:
typescript
private setAttendance(id: number, status: string): void {
this.courses = this.courses.map((course: Course) => {
if (course.id === id) {
return {
id: course.id,
name: course.name,
teacher: course.teacher,
location: course.location,
dayOfWeek: course.dayOfWeek,
startSection: course.startSection,
endSection: course.endSection,
startWeek: course.startWeek,
endWeek: course.endWeek,
color: course.color,
attendance: status
};
}
return course;
});
}
可以将课程标记为出勤、迟到、请假或缺勤状态。
切换周视图
页面支持切换查看不同周的课程表:
typescript
private changeWeek(delta: number): void {
const newWeek = this.currentWeek + delta;
if (newWeek >= 1 && newWeek <= 20) {
this.currentWeek = newWeek;
}
}
private getWeekCourses(): Course[] {
return this.courses.filter(
(course: Course) =>
this.currentWeek >= course.startWeek &&
this.currentWeek <= course.endWeek &&
(this.filterDay === 0 || course.dayOfWeek === this.filterDay)
);
}
支持查看第1-20周的课程,可以按星期筛选。
获取指定星期和节次的课程
用于课程表网格布局:
typescript
private getCourseAt(day: number, section: number): Course | null {
const courses = this.getWeekCourses();
for (let i = 0; i < courses.length; i++) {
const course = courses[i];
if (course.dayOfWeek === day &&
section >= course.startSection &&
section <= course.endSection) {
return course;
}
}
return null;
}
用于在课程表网格中正确显示跨节次的课程。
星期和节次选择
页面支持选择上课星期和节次:
typescript
@Builder
DayButton(day: number, text: string) {
Button(text)
.height(34)
.layoutWeight(1)
.fontSize(12)
.fontColor(this.selectedDay === day ? Color.White : '#344054')
.backgroundColor(
this.selectedDay === day ? '#4F46E5' : '#F3F4F6'
)
.borderRadius(8)
.onClick(() => {
this.selectedDay = day;
});
}
@Builder
FilterDayButton(day: number, text: string) {
Button(text)
.height(32)
.padding({ left: 10, right: 10 })
.fontSize(12)
.fontColor(this.filterDay === day ? Color.White : '#344054')
.backgroundColor(
this.filterDay === day ? '#4F46E5' : '#EEF2FF'
)
.borderRadius(16)
.onClick(() => {
this.filterDay = day;
});
}
使用靛蓝色作为主题色高亮当前选择。
选择课程颜色
页面支持多种课程颜色选择:
typescript
@Builder
ColorButton(color: string) {
Button()
.width(32)
.height(32)
.backgroundColor(color)
.borderRadius(16)
.borderWidth(this.selectedColor === color ? 3 : 0)
.borderColor('#1F2937')
.onClick(() => {
this.selectedColor = color;
});
}
不同课程使用不同颜色,便于在课程表中区分。
统计考勤数据
统计各类考勤状态的课程数量:
typescript
private getAttendanceCount(status: string): number {
const weekCourses = this.getWeekCourses();
if (status === '总课程') {
return weekCourses.length;
}
return weekCourses.filter(
(course: Course) => course.attendance === status
).length;
}
顶部统计区域展示本周总课程、出勤、迟到、请假和缺勤数量:
typescript
this.StatCard(
'本周课程',
`${this.getAttendanceCount('总课程')}`,
'#4F46E5',
'#EEF2FF'
);
this.StatCard(
'出勤',
`${this.getAttendanceCount('出勤')}`,
'#059669',
'#ECFDF5'
);
this.StatCard(
'迟到',
`${this.getAttendanceCount('迟到')}`,
'#D97706',
'#FFF7E8'
);
this.StatCard(
'缺勤',
`${this.getAttendanceCount('缺勤')}`,
'#DC2626',
'#FEF2F2'
);
设置考勤状态颜色
不同考勤状态使用不同颜色:
typescript
private getAttendanceColor(attendance: string): ResourceColor {
if (attendance === '出勤') {
return '#059669';
}
if (attendance === '迟到') {
return '#D97706';
}
if (attendance === '请假') {
return '#2563EB';
}
if (attendance === '缺勤') {
return '#DC2626';
}
return '#6B7280';
}
private getAttendanceBgColor(attendance: string): ResourceColor {
if (attendance === '出勤') {
return '#DCFCE7';
}
if (attendance === '迟到') {
return '#FEF3C7';
}
if (attendance === '请假') {
return '#DBEAFE';
}
if (attendance === '缺勤') {
return '#FEE2E2';
}
return '#F3F4F6';
}
颜色含义如下:
- 绿色:出勤
- 橙色:迟到
- 蓝色:请假
- 红色:缺勤
- 灰色:未开始
- 靛蓝色:页面主题色
删除课程
不需要的课程可以删除:
typescript
private deleteCourse(id: number): void {
this.courses = this.courses.filter(
(course: Course) => course.id !== id
);
}
删除后,课程表和统计数据会自动更新。
使用网格展示课程表
使用 Grid 渲染课程表布局:
typescript
Grid() {
ForEach([1, 2, 3, 4, 5, 6, 7], (day: number) => {
GridItem() {
Text(this.getDayName(day))
.fontSize(12)
.fontColor('#6B7280')
.width('100%')
.textAlign(TextAlign.Center)
}
.backgroundColor('#F9FAFB')
.padding(8)
})
ForEach(this.getSectionsForWeek(), (section: number) => {
ForEach([1, 2, 3, 4, 5, 6, 7], (day: number) => {
GridItem() {
this.CourseGridCell(day, section)
}
})
})
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')
.rowsGap(2)
.columnsGap(2)
.width('100%')
.backgroundColor('#E5E7EB')
.padding(2)
.borderRadius(8)
课程表使用7列(周一到周日),每节次一行,课程卡片使用对应颜色显示。
页面设计说明
应用使用靛蓝色作为主题色,适合学习工具专业简洁的风格。
页面主要分为以下区域:
- 顶部标题和周数切换
- 考勤数据统计区域
- 添加课程表单
- 星期筛选区域
- 课程表网格视图
- 课程列表和考勤操作
页面采用白色背景和彩色课程卡片。不同课程使用不同颜色区分,考勤状态使用对应颜色标签,课程表采用网格布局,清晰展示每周课程安排。
SDK 配置
本项目使用 HarmonyOS API 24,满足 API 23 及以上要求:
json5
{
"name": "default",
"compatibleSdkVersion": "6.1.1(24)",
"runtimeOS": "HarmonyOS",
"targetSdkVersion": "6.1.1(24)",
"compileSdkVersion": "6.1.1(24)"
}
entry 模块中的运行系统也要保持一致:
json5
{
"apiType": "stageMode",
"targets": [
{
"name": "default",
"runtimeOS": "HarmonyOS"
}
]
}
运行项目
使用 DevEco Studio 打开项目,然后找到:
entry/src/main/ets/pages/Index.ets
等待项目同步完成,点击右侧的 Preview 按钮即可查看应用效果。
项目总结
本文使用 HarmonyOS 和 ArkTS 实现了一个校园课程表与考勤管理应用。
项目实现了课程添加、时间地点设置、教师信息、周数范围、课程颜色、考勤记录、周视图切换、星期筛选、考勤统计和课程删除等功能。
通过这个项目可以掌握:
- ArkTS 接口定义
@State状态管理Grid网格布局实现课程表List和ForEach列表渲染map和filter数组操作- 多状态考勤管理
- 周视图切换逻辑
- 自定义
@Builder组件 - HarmonyOS 课程表布局
后续还可以加入上课时间提醒、考试倒计时、成绩记录、作业管理、课表导入导出、桌面小组件和云端同步等功能。