HarmonyOS ArkTS 实战:实现一个校园课程表与考勤管理应用

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列(周一到周日),每节次一行,课程卡片使用对应颜色显示。

页面设计说明

应用使用靛蓝色作为主题色,适合学习工具专业简洁的风格。

页面主要分为以下区域:

  1. 顶部标题和周数切换
  2. 考勤数据统计区域
  3. 添加课程表单
  4. 星期筛选区域
  5. 课程表网格视图
  6. 课程列表和考勤操作

页面采用白色背景和彩色课程卡片。不同课程使用不同颜色区分,考勤状态使用对应颜色标签,课程表采用网格布局,清晰展示每周课程安排。

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 网格布局实现课程表
  • ListForEach 列表渲染
  • mapfilter 数组操作
  • 多状态考勤管理
  • 周视图切换逻辑
  • 自定义 @Builder 组件
  • HarmonyOS 课程表布局

后续还可以加入上课时间提醒、考试倒计时、成绩记录、作业管理、课表导入导出、桌面小组件和云端同步等功能。

相关推荐
风华圆舞2 小时前
鸿蒙HarmonyOS 多模态输入实战 —— 图片与文档输入智谱/DeepSeek
开发语言·人工智能·华为·php·harmonyos·arkts·arkui
AD02273 小时前
31-后台任务重复执行-用唯一任务键和租约防止并发
harmonyos·arkts·鸿蒙开发
我是小a3 小时前
HarmonyOS API 24 List组件与数据渲染技术详解
华为·harmonyos·鸿蒙
我是小a3 小时前
HarmonyOS API 24 交互事件与动画效果技术详解
华为·harmonyos·鸿蒙
不肥嘟嘟右卫门3 小时前
鸿蒙原生ArkTS布局方式之List垂直列表布局深度解析
华为·list·harmonyos
listening7773 小时前
HarmonyOS 6.1 端云协同大模型实战:隐私不泄露的智能导购落地
华为·harmonyos
xd1855785554 小时前
SQL语句生成-基于鸿蒙的AI SQL语句生成应用开发实践
人工智能·sql·华为·harmonyos·鸿蒙
funnycoffee1234 小时前
华为USG防火墙端口有收光,无法UP故障
服务器·网络·华为
鸿蒙程序媛5 小时前
【工具汇总】鸿蒙 ArkWeb完整调试工具步骤
华为·harmonyos