HarmonyOS ArkTS 实战:实现一个校园迎新与报到注册应用

项目效果

本文使用 HarmonyOS 和 ArkTS 实现一个校园迎新与报到注册应用。

应用可以帮助新生完成线上报到,填写个人信息,缴纳学费,查看报到流程,分配宿舍,并提供迎新志愿者对接、报到统计和流程进度跟踪等功能。

项目使用 DevEco Studio 开发,适配 API 23 及以上版本。

运行效果

校园迎新与报到注册应用

功能介绍

本项目实现了以下功能:

  • 新生信息填写
  • 报到流程指引
  • 学费缴纳
  • 宿舍分配查询
  • 班级和辅导员信息
  • 迎新志愿者对接
  • 报到进度跟踪
  • 绿色通道申请
  • 报到统计
  • 校园地图导航
  • 常见问题解答

定义数据结构

首先定义报到流程和新生信息的数据结构:

interface ReportStep {
  id: number;
  name: string;
  description: string;
  location: string;
  status: string;
  completeTime: string;
}

interface NewStudent {
  id: number;
  studentId: string;
  name: string;
  gender: string;
  idCard: string;
  college: string;
  major: string;
  className: string;
  counselor: string;
  counselorPhone: string;
  dormBuilding: string;
  dormRoom: string;
  volunteer: string;
  volunteerPhone: string;
  totalFee: number;
  paidFee: number;
  reportStatus: string;
  reportTime: string;
  steps: ReportStep[];
}

字段说明如下:

  • ReportStep:报到步骤
    • id:步骤编号
    • name:步骤名称
    • description:步骤说明
    • location:办理地点
    • status:状态(未开始/进行中/已完成)
    • completeTime:完成时间
  • NewStudent:新生信息
    • id:编号
    • studentId:学号
    • name:姓名
    • gender:性别
    • idCard:身份证号
    • college:学院
    • major:专业
    • className:班级
    • counselor:辅导员
    • counselorPhone:辅导员电话
    • dormBuilding:宿舍楼
    • dormRoom:宿舍号
    • volunteer:对接志愿者
    • volunteerPhone:志愿者电话
    • totalFee:应缴费用
    • paidFee:已缴费用
    • reportStatus:报到状态(未报到/报到中/已报到)
    • reportTime:报到时间
    • steps:报到步骤列表

初始化页面状态

使用 @State 保存新生信息、当前步骤:

@State private nameText: string = '';
@State private studentIdText: string = '';
@State private idCardText: string = '';
@State private phoneText: string = '';
@State private currentStep: number = 0;
@State private greenChannel: boolean = false;
@State private nextStudentId: number = 2;

准备一些初始新生数据:

@State private students: NewStudent[] = [
  {
    id: 1,
    studentId: '20260001',
    name: '张新生',
    gender: '男',
    idCard: '310***********1234',
    college: '计算机学院',
    major: '计算机科学与技术',
    className: '计科2601班',
    counselor: '李老师',
    counselorPhone: '138****1001',
    dormBuilding: '12号楼',
    dormRoom: '302室',
    volunteer: '王学长',
    volunteerPhone: '139****2002',
    totalFee: 7800,
    paidFee: 7800,
    reportStatus: '已报到',
    reportTime: '2026-09-01 09:30',
    steps: [
      { id: 1, name: '身份验证', description: '核验录取通知书和身份证', location: '正门迎新点', status: '已完成', completeTime: '2026-09-01 08:30' },
      { id: 2, name: '学院报到', description: '到学院迎新点登记', location: '计算机学院楼', status: '已完成', completeTime: '2026-09-01 08:50' },
      { id: 3, name: '费用缴纳', description: '缴纳学费住宿费', location: '财务处', status: '已完成', completeTime: '2026-09-01 09:00' },
      { id: 4, name: '宿舍入住', description: '领取钥匙入住宿舍', location: '12号楼', status: '已完成', completeTime: '2026-09-01 09:20' },
      { id: 5, name: '领取物资', description: '领取军训服和校园卡', location: '大学生活动中心', status: '已完成', completeTime: '2026-09-01 09:30' }
    ]
  }
];

新生报到注册

新生填写信息完成报到:

private submitReport(): void {
  const name = this.nameText.trim();
  const studentId = this.studentIdText.trim();
  const idCard = this.idCardText.trim();

  if (name.length === 0 || studentId.length === 0 || idCard.length === 0) {
    return;
  }

  const steps: ReportStep[] = [
    { id: 1, name: '身份验证', description: '核验录取通知书和身份证', location: '正门迎新点', status: '进行中', completeTime: '' },
    { id: 2, name: '学院报到', description: '到学院迎新点登记', location: '各学院楼', status: '未开始', completeTime: '' },
    { id: 3, name: '费用缴纳', description: '缴纳学费住宿费', location: '财务处/线上', status: '未开始', completeTime: '' },
    { id: 4, name: '宿舍入住', description: '领取钥匙入住宿舍', location: '各宿舍楼', status: '未开始', completeTime: '' },
    { id: 5, name: '领取物资', description: '领取军训服和校园卡', location: '大学生活动中心', status: '未开始', completeTime: '' }
  ];

  const student: NewStudent = {
    id: this.nextStudentId,
    studentId,
    name,
    gender: '男',
    idCard,
    college: '计算机学院',
    major: '计算机科学与技术',
    className: '计科2601班',
    counselor: '李老师',
    counselorPhone: '138****1001',
    dormBuilding: '12号楼',
    dormRoom: '305室',
    volunteer: '王学长',
    volunteerPhone: '139****2002',
    totalFee: this.greenChannel ? 0 : 7800,
    paidFee: 0,
    reportStatus: '报到中',
    reportTime: '',
    steps
  };

  this.students = [student, ...this.students];
  this.nextStudentId += 1;
  this.nameText = '';
  this.studentIdText = '';
  this.idCardText = '';
  this.phoneText = '';
}

完成报到步骤

逐步完成报到流程:

private completeStep(studentId: number, stepId: number): void {
  const now = new Date();
  const timeStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}`;

  this.students = this.students.map((student: NewStudent) => {
    if (student.studentId === studentId) {
      const updatedSteps = student.steps.map((step: ReportStep, index: number) => {
        if (step.id === stepId) {
          return { ...step, status: '已完成', completeTime: timeStr };
        }
        if (step.status === '未开始' && student.steps[index - 1]?.id === stepId) {
          return { ...step, status: '进行中' };
        }
        return step;
      });

      const allCompleted = updatedSteps.every(s => s.status === '已完成');
      const allPaid = student.paidFee >= student.totalFee;

      return {
        ...student,
        steps: updatedSteps,
        reportStatus: allCompleted && allPaid ? '已报到' : '报到中',
        reportTime: allCompleted && allPaid ? timeStr : ''
      };
    }
    return student;
  });
}

缴纳学费

private payFee(studentId: number, amount: number): void {
  this.students = this.students.map((student: NewStudent) => {
    if (student.studentId === studentId) {
      const newPaid = Math.min(student.paidFee + amount, student.totalFee);
      return { ...student, paidFee: newPaid };
    }
    return student;
  });
}

绿色通道申请

家庭经济困难学生可以申请绿色通道:

private applyGreenChannel(studentId: number): void {
  this.students = this.students.map((student: NewStudent) => {
    if (student.studentId === studentId) {
      return { ...student, totalFee: 0, greenChannel: true };
    }
    return student;
  });
}

报到进度计算

private getProgress(student: NewStudent): number {
  const completed = student.steps.filter(s => s.status === '已完成').length;
  return Math.round((completed / student.steps.length) * 100);
}

统计数据

private getTotalStudents(): number {
  return this.students.length;
}

private getReportedCount(): number {
  return this.students.filter(s => s.reportStatus === '已报到').length;
}

private getReportingCount(): number {
  return this.students.filter(s => s.reportStatus === '报到中').length;
}

private getTotalFeePaid(): number {
  return this.students.reduce((sum, s) => sum + s.paidFee, 0);
}

顶部统计区域展示总人数、已报到、报到中、已缴费用:

this.StatCard(
  '新生总数',
  `${this.getTotalStudents()}`,
  '#0EA5E9',
  '#F0F9FF'
);
this.StatCard(
  '已报到',
  `${this.getReportedCount()}`,
  '#059669',
  '#ECFDF5'
);
this.StatCard(
  '报到中',
  `${this.getReportingCount()}`,
  '#F59E0B',
  '#FFFBEB'
);
this.StatCard(
  '已缴费用',
  `¥${this.getTotalFeePaid()}`,
  '#2563EB',
  '#EFF6FF'
);

设置状态颜色

private getStepStatusColor(status: string): ResourceColor {
  if (status === '已完成') return '#059669';
  if (status === '进行中') return '#0EA5E9';
  return '#9CA3AF';
}

private getReportStatusColor(status: string): ResourceColor {
  if (status === '已报到') return '#059669';
  if (status === '报到中') return '#F59E0B';
  return '#DC2626';
}

private getReportStatusBgColor(status: string): ResourceColor {
  if (status === '已报到') return '#DCFCE7';
  if (status === '报到中') return '#FEF3C7';
  return '#FEE2E2';
}
  • 绿色:已完成/已报到
  • 天蓝色:进行中
  • 橙色:报到中
  • 红色:未报到
  • 灰色:未开始
  • 天蓝色系:页面主题色

报到流程时间线

使用垂直时间线展示报到步骤:

Column() {
  ForEach(
    student.steps,
    (step: ReportStep, index: number) => {
      Row() {
        Column() {
          Circle()
            .width(24)
            .height(24)
            .fill(this.getStepStatusColor(step.status))
          if (index < student.steps.length - 1) {
            Divider()
              .vertical(true)
              .height(40)
              .color('#E5E7EB')
          }
        }
        .width(30)
        .alignItems(HorizontalAlign.Center)

        Column() {
          Text(step.name)
            .fontSize(15)
            .fontWeight(FontWeight.Medium)
            .fontColor('#111827')
          Text(step.description)
            .fontSize(12)
            .fontColor('#6B7280')
            .margin({ top: 4 })
          Text(`地点:${step.location}`)
            .fontSize(12)
            .fontColor('#0EA5E9')
            .margin({ top: 2 })
        }
        .alignItems(HorizontalAlign.Start)
        .layoutWeight(1)
        .margin({ left: 12 })
      }
      .width('100%')
      .alignItems(VerticalAlign.Top)
    },
    (step: ReportStep) => step.id.toString()
  )
}
.width('100%')

页面设计说明

应用使用天蓝色作为主题色,体现青春、欢迎、希望的迎新氛围。

页面主要分为以下区域:

  1. 顶部欢迎横幅
  2. 报到数据统计
  3. 新生报到表单
  4. 我的报到信息卡片
  5. 报到流程时间线
  6. 缴费和绿色通道入口
  7. 志愿者和辅导员联系信息

页面采用浅灰色背景和白色卡片。报到进度使用进度条展示,流程步骤使用时间线样式,已完成步骤使用绿色对勾标记,进行中步骤使用天蓝色高亮,联系电话使用可点击样式。

SDK 配置

本项目使用 HarmonyOS API 24,满足 API 23 及以上要求:

{
  "name": "default",
  "compatibleSdkVersion": "6.1.1(24)",
  "runtimeOS": "HarmonyOS",
  "targetSdkVersion": "6.1.1(24)",
  "compileSdkVersion": "6.1.1(24)"
}

entry 模块中的运行系统也要保持一致:

{
  "apiType": "stageMode",
  "targets": [
    {
      "name": "default",
      "runtimeOS": "HarmonyOS"
    }
  ]
}

运行项目

使用 DevEco Studio 打开项目,然后找到:

entry/src/main/ets/pages/Index.ets

等待项目同步完成,点击右侧的 Preview 按钮即可查看应用效果。

项目总结

本文使用 HarmonyOS 和 ArkTS 实现了一个校园迎新与报到注册应用。

项目实现了新生信息填写、报到流程指引、学费缴纳、宿舍分配查询、志愿者对接、进度跟踪、绿色通道、报到统计等功能。

通过这个项目可以掌握:

  • ArkTS 接口定义和步骤数据结构
  • @State 状态管理
  • 流程进度跟踪
  • 时间线组件布局
  • ListForEach 列表渲染
  • 进度条计算
  • 自定义 @Builder 组件
  • HarmonyOS 迎新类应用布局

后续还可以加入人脸识别报到、扫码签到、校园导航、新生群聊、迎新直播、家长端、行李托运、军训服装尺码选择和报到预约时段等功能。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐